通過實例解析json與jsonp原理及使用方法
1.json與jsonp的引入
在ajax中 JSON用來解決數(shù)據(jù)交換問題,而JSONP來實現(xiàn)跨域。
備注:跨域也可以通過服務(wù)器端代理來解決;
理解:JSON是一種數(shù)據(jù)交換格式,而JSONP是一種依靠開發(fā)人員的聰明才智創(chuàng)造出的一種非官方跨域數(shù)據(jù)交互協(xié)議。
2.JSON:是一種基于文本的數(shù)據(jù)交換方式,或者叫做數(shù)據(jù)描述格式,是否該選用它首先肯定要關(guān)注它所擁有的優(yōu)點。
JSON的優(yōu)點:
- 1) 基于純文本,跨平臺傳遞極其簡單;
- 2) Javascript原生支持,后臺語言幾乎全部支持;
- 3) 輕量級數(shù)據(jù)格式,占用字符數(shù)量極少,特別適合互聯(lián)網(wǎng)傳遞;
- 4) 可讀性較強,雖然比不上XML那么一目了然,但在合理的依次縮進之后還是很容易識別的;
- 5) 容易編寫和解析,當然前提是你要知道數(shù)據(jù)結(jié)構(gòu);
JSON的格式或者叫規(guī)則:
JSON能夠以非常簡單的方式來描述數(shù)據(jù)結(jié)構(gòu),XML能做的它都能做,因此在跨平臺方面兩者完全不分伯仲。
- 1) JSON只有兩種數(shù)據(jù)類型描述符,大括號{}和方括號[],其余英文冒號:是映射符,英文逗號,是分隔符,英文雙引號""是定義符。
- 2) 大括號{}用來描述一組“不同類型的無序鍵值對集合”(每個鍵值對可以理解為OOP的屬性描述),方括號[]用來描述一組“相同類型的有序數(shù)據(jù)集合”(可對應(yīng)OOP的數(shù)組)。
- 3) 上述兩種集合中若有多個子項,則通過英文逗號,進行分隔。
- 4) 鍵值對以英文冒號:進行分隔,并且建議鍵名都加上英文雙引號"",以便于不同語言的解析。
- 5) JSON內(nèi)部常用數(shù)據(jù)類型無非就是字符串、數(shù)字、布爾、日期、null 這么幾個,字符串必須用雙引號引起來,其余的都不用,日期類型比較特殊,這里就不展開講述了,
只是建議如果客戶端沒有按日期排序功能需求的話,那么把日期時間直接作為字符串傳遞就好,可以省去很多麻煩。
示列1:{} 用來描述一組“不同類型的無序鍵值對集合”
var person = {
"Name": "Bob",
"Age": 32,
"Company": "IBM",
"Engineer": true
}
示列2:[] 用來描述一組“相同類型的有序數(shù)據(jù)集合”
var members = [
{
"Name": "Bob",
"Age": 32,
"Company": "IBM",
"Engineer": true
},
{
"Name": "John",
"Age": 20,
"Company": "Oracle",
"Engineer": false
},
{
"Name": "Henry",
"Age": 45,
"Company": "Microsoft",
"Engineer": false
}
]
//讀取其中John的公司名稱
var johnsCompany = members[1].Company;
示列3:{}中包含的[]使用
var conference = {
"Conference": "Future Marketing",
"Date": "2012-6-1",
"Address": "Beijing",
"Members":
[
{
"Name": "Bob",
"Age": 32,
"Company": "IBM",
"Engineer": true
},
{
"Name": "John",
"Age": 20,
"Company": "Oracle",
"Engineer": false
},
{
"Name": "Henry",
"Age": 45,
"Company": "Microsoft",
"Engineer": false
}
]
}
// 讀取參會者Henry是否工程師
var henryIsAnEngineer = conference.Members[2].Engineer;
3.什么是JSONP
JSONP(JSON with Padding)是資料格式 JSON 的一種“使用模式”,可以讓網(wǎng)頁從別的網(wǎng)域要資料。由于同源策略,一般來說位于 server1.example.com 的網(wǎng)頁無法與不是 server1.example.com的服務(wù)器溝通,而 HTML 的 <script> 元素是一個例外。利用<script> 元素的這個開放策略,網(wǎng)頁可以得到從其他來源動態(tài)產(chǎn)生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料并不是 JSON,而是任意的 JavaScript,用 JavaScript 直譯器執(zhí)行而不是用 JSON 解析器解析。
3.1 JSOPN跨域的原理:script標簽的src屬性,支持跨域;它的基本思想是,網(wǎng)頁通過添加一個<script>元素,向服務(wù)器請求JSON數(shù)據(jù),這種做法不受同源政策限制;服務(wù)器收到請求后,將數(shù)據(jù)放在一個指定名字的回調(diào)函數(shù)里傳回來。
3.2 JSOP包含兩部分:回調(diào)函數(shù)和數(shù)據(jù),回調(diào)函數(shù)是在響應(yīng)到來時應(yīng)該調(diào)用的函數(shù),一般通過查詢字符串添加; 數(shù)據(jù)就是傳入回調(diào)函數(shù)中的JSON數(shù)據(jù),確切的說,是一個JSON對象,可以直接訪問。
3.3 JSONP的缺點:
1) 只能實現(xiàn)GET,沒有POST;
2) 從其他域中加載的代碼可能不安全;難以確定JSONP請求是否失?。╔HR有error事件),常見做法是使用定時器指定響應(yīng)的允許時間,超出時間認為響應(yīng)失敗。
為了方便客戶端使用數(shù)據(jù)逐漸形成非正式傳輸協(xié)議jsonp該協(xié)議的一個要點就是允許用戶傳遞一個callback參數(shù)給服務(wù)端,然后服務(wù)端返回數(shù)據(jù)時會將這個callback參數(shù)作為函數(shù)名來包裹住json數(shù)據(jù) 這樣客戶端就可以隨意定制自己的函數(shù)來自動處理返回數(shù)據(jù)
示列:
function ajaxFun(){
var strUrl="http://www.b.com/demo/json.txt";
$.ajax({
type:"get",
url:strUrl,
dataType: 'jsonp',
jsonp: "callback",//傳遞給請求處理程序或頁面的,用以獲得jsonp回調(diào)函數(shù)名的參數(shù)名(一般默認為:callback)
jsonpCallback: "flightHandler",//自定義的jsonp回調(diào)函數(shù)名稱,默認為jQuery自動生成的隨機函數(shù)名,也可以寫"?",jQuery會自動為你處理數(shù)據(jù)
success: function(data){
alert('您查到的信息:票價' + data.price + '元,余-票' + data.tickets + '張。');
},
error: function(XMLHttpRequest,textStatus,errorThrown){
alert("error");
// 狀態(tài)碼
console.log(XMLHttpRequest.status);
// 狀態(tài)
console.log(XMLHttpRequest.readyState);
// 錯誤信息
console.log(textStatus);
}
});
}
備注:
其中 sucess中的代碼片段也可以不寫,可以單獨建立一個回調(diào)函數(shù)來調(diào)用返回的數(shù)據(jù)。如下一樣可以獲得數(shù)據(jù)。
var flightHandler = function (data) {
alert('您查到的信息:票價' + data.price + '元,余票' + data.tickets + '張。');
};
需要注意的是,ajax跨域請求(jsonp)中,服務(wù)端返回數(shù)據(jù)格式必須是:flightHandler({ "price":"120","tickets":"20"});如果直接這樣的json格式{ "price":"120","tickets":"20"},將會報parser error的錯誤.請注意這個函數(shù)最后的分號";",必須加上,否則,如果同一個頁面有多個ajax請求, 并且在數(shù)據(jù)沒有返回時,再發(fā)出其它ajax請求時,有可能出現(xiàn)parsererror出錯提示.這種錯誤很隱敝,在開發(fā)時,不容易發(fā)現(xiàn),在并發(fā)測試時,就很容易暴露出.
服務(wù)端代碼示列:
public String jsonReturn(HttpServletResponse response, String callback, Map<String, Object> jsonMap) {
if (org.apache.commons.lang.StringUtils.isEmpty(callback)) {
return appAjaxJson(response, getJson(jsonMap));
}
return appAjaxJson(response, callback + "(" + getJson(jsonMap) + ")");
}
public String appAjaxJson(HttpServletResponse response, String jsonString) {
return appAjax(response, jsonString, "text/html");
}
public String appAjax(HttpServletResponse response, String content, String type) {
try {
response.setContentType(type + ";charset=UTF-8");
response.setHeader("Access-Control-Allow-Origin", "*");//表示支持跨域請求
// 如果IE瀏覽器則設(shè)置頭信息如下
if ("IE".equals(type)) {
response.addHeader("XDomainRequestAllowed", "1");
}
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.getWriter().write(content);
response.getWriter().flush();
} catch (IOException e) {
this.logException(e);
}
return null;
}
4、JSON.stringify()、JSON.parse()、toString()
4.1 JSON.stringify():將入?yún)?JavaScript值)轉(zhuǎn)換為 JSON 字符串;
示列1:
let arr = [1,2,3];
JSON.stringify(arr);//"[1,2,3]"
typeof JSON.stringify(arr);//"string"
示例2:
//判斷數(shù)組是否包含某對象
let data = [
{name:'echo'},
{name:'聽風是風'},
{name:'天子笑'},
],
val = {name:'天子笑'};
JSON.stringify(data).indexOf(JSON.stringify(val)) !== -1;//true
//判斷兩數(shù)組/對象是否相等
let a = [1,2,3],
b = [1,2,3];
JSON.stringify(a) === JSON.stringify(b);//true
4.2 JSON.parse():將JSON字符串轉(zhuǎn)為一個對象;
示列:
let string = '[1,2,3]';
console.log(JSON.parse(string))//[1,2,3]
console.log(typeof JSON.parse(string))//object
4.3 JSON.stringify()與 toString()的區(qū)別
let arr = [1,2,3];
JSON.stringify(arr);//'[1,2,3]'
arr.toString();//1,2,3
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
微信小程序wx.getUserInfo授權(quán)獲取用戶信息(頭像、昵稱)的實現(xiàn)
這篇文章主要介紹了微信小程序wx.getUserInfo授權(quán)獲取用戶信息(頭像、昵稱)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
基于JS實現(xiàn)Flappy?Bird游戲的示例代碼
Flappy?Bird是13年紅極一時的小游戲,即摁上鍵控制鳥的位置穿過管道間的縫隙。本文將用JS實現(xiàn)這一經(jīng)典的游戲,需要的可以參考一下2022-04-04
vue?element?loading遮罩層添加按鈕功能實現(xiàn)
這篇文章主要介紹了vue?element?loading遮罩層添加按鈕功能實現(xiàn),通過實例代碼補充介紹了vue+elementui的this.$loading遮罩使用方法,需要的朋友可以參考下2024-03-03
為JavaScript類型增加方法的實現(xiàn)代碼(增加功能)
大家在js開發(fā)過程中有些功能已經(jīng)滿足不了我們的需求,或沒有我們需要的功能,那么我們就可以自己擴展下,個性化js2011-12-12
詳解利用exif.js解決ios手機上傳豎拍照片旋轉(zhuǎn)90度問題
這篇文章主要介紹了詳解利用exif.js解決ios手機上傳豎拍照片旋轉(zhuǎn)90度問題,有需要的朋友可以了解一下。2016-11-11
JavaScript中ES6規(guī)范中l(wèi)et和const的用法和區(qū)別
這篇文章主要介紹了JavaScript中ES6規(guī)范中l(wèi)et和const的用法和區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08

