Json和Jsonp理論實(shí)例代碼詳解
什么是Json?
JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一個(gè)子集。 JSON采用
完全獨(dú)立于語(yǔ)言的文本格式,但是也使用了類似于C語(yǔ)言家族的習(xí)慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。這些特性使JSON成為理想的數(shù)據(jù)交換語(yǔ)言。易于人
閱讀和編寫,同時(shí)也易于機(jī)器解析和生成。
JSON有兩種結(jié)構(gòu):
json簡(jiǎn)單說(shuō)就是javascript中的對(duì)象和數(shù)組,所以這兩種結(jié)構(gòu)就是對(duì)象和數(shù)組2種結(jié)構(gòu),通過(guò)這兩種結(jié)構(gòu)可以表示各種復(fù)雜的結(jié)構(gòu)
1、對(duì)象:對(duì)象在js中表示為“{}”擴(kuò)起來(lái)的內(nèi)容,數(shù)據(jù)結(jié)構(gòu)為 {key:value,key:value,...}的鍵值對(duì)的結(jié)構(gòu),在面向?qū)ο蟮恼Z(yǔ)言中,key為對(duì)象的屬性,value為對(duì)應(yīng)的屬性值,所以很容易理解,取值方法為 對(duì)象.key 獲取屬性值,這個(gè)屬性值的類型可以是 數(shù)字、字符串、數(shù)組、對(duì)象幾種。
2、數(shù)組:數(shù)組在js中是中括號(hào)“[]”擴(kuò)起來(lái)的內(nèi)容,數(shù)據(jù)結(jié)構(gòu)為 ["java","javascript","vb",...],取值方式和所有語(yǔ)言中一樣,使用索引獲取,字段值的類型可以是 數(shù)字、字符串、數(shù)組、對(duì)象幾種。
經(jīng)過(guò)對(duì)象、數(shù)組2種結(jié)構(gòu)就可以組合成復(fù)雜的數(shù)據(jù)結(jié)構(gòu)了。
JSON的格式或者叫規(guī)則:
JSON能夠以非常簡(jiǎn)單的方式來(lái)描述數(shù)據(jù)結(jié)構(gòu),XML能做的它都能做,因此在跨平臺(tái)方面兩者完全不分伯仲。
1、JSON只有兩種數(shù)據(jù)類型描述符,大括號(hào){}和方括號(hào)[],其余英文冒號(hào):是映射符,英文逗號(hào),是分隔符,英文雙引號(hào)""是定義符。
2、大括號(hào){}用來(lái)描述一組“不同類型的無(wú)序鍵值對(duì)集合”(每個(gè)鍵值對(duì)可以理解為OOP的屬性描述),方括號(hào)[]用來(lái)描述一組“相同類型的有序數(shù)據(jù)集合”(可對(duì)應(yīng)OOP的數(shù)組)。
3、上述兩種集合中若有多個(gè)子項(xiàng),則通過(guò)英文逗號(hào),進(jìn)行分隔。
4、鍵值對(duì)以英文冒號(hào):進(jìn)行分隔,并且建議鍵名都加上英文雙引號(hào)"",以便于不同語(yǔ)言的解析。
5、JSON內(nèi)部常用數(shù)據(jù)類型無(wú)非就是字符串、數(shù)字、布爾、日期、null 這么幾個(gè),字符串必須用雙引號(hào)引起來(lái),其余的都不用,日期類型比較特殊,這里就不展開講述了,只是建議如果客戶端沒有按日期排序功能需求的話,那么把日期時(shí)間直接作為字符串傳遞就好,可以省去很多麻煩。
JSON實(shí)例
// 描述一個(gè)人
var Person = {
"Name": "aehyok",
"Age": 25,
"Company": "aehyok",
"Engineer": true
}
//獲取這個(gè)人的信息
var PersonAge = Person.Age;
alert(PersonAge);
//描述幾個(gè)人
var members = [
{
"Name": "aehyok",
"Age": 25,
"Company": "aehyok",
"Engineer": true
},
{
"Name": "lqm",
"Age": 25,
"Company": "Oracle",
"Engineer": false
},
{
"Name": "thl",
"Age": 22,
"Company": "Microsoft",
"Engineer": false
}
]
// 讀取其中l(wèi)qm的公司名稱
var lqmCompany = members[1].Company;
alert(lqmCompany);
// 描述一次會(huì)議
var conference = {
"Conference": "Future Marketing",
"Date": "2013-5-22",
"Address": "ShenZhen",
"Members":
[
{
"Name": "aehyok",
"Age": 25,
"Company": "IBM",
"Engineer": true
},
{
"Name": "lqm",
"Age": 25,
"Company": "Oracle",
"Engineer": false
},
{
"Name": "Thl",
"Age": 20,
"Company": "Microsoft",
"Engineer": false
}
]
}
// 讀取參會(huì)者Thl是否工程師
var ThlIsAnEngineer = conference.Members[2].Engineer;
alert(ThlIsAnEngineer);
什么是Jsonp
1、一個(gè)眾所周知的問題,Ajax直接請(qǐng)求普通文件存在跨域無(wú)權(quán)限訪問的問題,甭管你是靜態(tài)頁(yè)面、動(dòng)態(tài)網(wǎng)頁(yè)、web服務(wù)、WCF,只要是跨域請(qǐng)求,一律不準(zhǔn);
2、不過(guò)我們又發(fā)現(xiàn),Web頁(yè)面上調(diào)用js文件時(shí)則不受是否跨域的影響(不僅如此,我們還發(fā)現(xiàn)凡是擁有"src"這個(gè)屬性的標(biāo)簽都擁有跨域的能力,比如<script>、<img>、<iframe>);
3、于是可以判斷,當(dāng)前階段如果想通過(guò)純web端(ActiveX控件、服務(wù)端代理、屬于未來(lái)的HTML5之Websocket等方式不算)跨域訪問數(shù)據(jù)就只有一種可能,那就是在遠(yuǎn)程服務(wù)器上設(shè)法把數(shù)據(jù)裝進(jìn)js格式的文件里,供客戶端調(diào)用和進(jìn)一步處理;
4、恰巧我們已經(jīng)知道有一種叫做JSON的純字符數(shù)據(jù)格式可以簡(jiǎn)潔的描述復(fù)雜數(shù)據(jù),更妙的是JSON還被js原生支持,所以在客戶端幾乎可以隨心所欲的處理這種格式的數(shù)據(jù);
5、這樣子解決方案就呼之欲出了,web客戶端通過(guò)與調(diào)用腳本一模一樣的方式,來(lái)調(diào)用跨域服務(wù)器上動(dòng)態(tài)生成的js格式文件(一般以JSON為后綴),顯而易見,服務(wù)器之所以要?jiǎng)討B(tài)生成JSON文件,目的就在于把客戶端需要的數(shù)據(jù)裝入進(jìn)去。
6、客戶端在對(duì)JSON文件調(diào)用成功之后,也就獲得了自己所需的數(shù)據(jù),剩下的就是按照自己需求進(jìn)行處理和展現(xiàn)了,這種獲取遠(yuǎn)程數(shù)據(jù)的方式看起來(lái)非常像AJAX,但其實(shí)并不一樣。
7、為了便于客戶端使用數(shù)據(jù),逐漸形成了一種非正式傳輸協(xié)議,人們把它稱作JSONP,該協(xié)議的一個(gè)要點(diǎn)就是允許用戶傳遞一個(gè)callback參數(shù)給服務(wù)端,然后服務(wù)端返回?cái)?shù)據(jù)時(shí)會(huì)將這個(gè)callback參數(shù)作為函數(shù)名來(lái)包裹住JSON數(shù)據(jù),這樣客戶端就可以隨意定制自己的函數(shù)來(lái)自動(dòng)處理返回?cái)?shù)據(jù)了。
如果對(duì)于callback參數(shù)如何使用還有些模糊的話,我們后面會(huì)有具體的實(shí)例來(lái)講解。
Jsonp的客戶端具體實(shí)現(xiàn):
1.先來(lái)個(gè)最簡(jiǎn)單的一個(gè)。首先我在IIS中建立了兩個(gè)網(wǎng)站,當(dāng)然端口一個(gè)是888另外一個(gè)是8888,我們就把888作為本地服務(wù)器,8888作為遠(yuǎn)程服務(wù)器的。
現(xiàn)在本地有這樣一個(gè)網(wǎng)頁(yè)
<html>
<head>
<title>index.html</title>
<script type="text/javascript" src="http://localhost:8888/remote.js" ></script>
</head>
<body></body>
</html>
其中JavaScript文件引用的是8888的remote.js文件。
alert('我是遠(yuǎn)程文件');
運(yùn)行本地服務(wù)器網(wǎng)站后效果為

現(xiàn)在最簡(jiǎn)單的跨域成功了。
2.我們?cè)?的基礎(chǔ)上進(jìn)行修改一下,先看代碼
<html>
<head>
<title>index.html</title>
<script type="text/javascript">
function aehyok(data)
{
alert(data.result);
}
</script>
<script type="text/javascript" src="http://localhost:8888/remote.js" ></script>
</head>
<body></body>
</html>
先將本地文件中添加一個(gè)js函數(shù),然后調(diào)用遠(yuǎn)程服務(wù)器的js文件。
aehyok({"result":"我是遠(yuǎn)程js帶來(lái)的數(shù)據(jù)"});
這是在遠(yuǎn)程服務(wù)端js文件中的代碼。
運(yùn)行后效果

調(diào)用成功。顯示本地函數(shù)被跨域的遠(yuǎn)程js調(diào)用成功,并且還接收到了遠(yuǎn)程js帶來(lái)的數(shù)據(jù)。很欣喜,跨域遠(yuǎn)程獲取數(shù)據(jù)的目的基本實(shí)現(xiàn)了,但是又一個(gè)問題出現(xiàn)了,我怎么讓遠(yuǎn)程js知道它應(yīng)該調(diào)用的本地函數(shù)叫什么名字呢?畢竟是jsonp的服務(wù)者都要面對(duì)很多服務(wù)對(duì)象,而這些服務(wù)對(duì)象各自的本地函數(shù)都不相同啊?我們接著往下看。
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "get",
async: false,
url: "../Home/aehyok",
dataType: "jsonp",
jsonp: "callback", //傳遞給請(qǐng)求處理程序或頁(yè)面的,用以獲得jsonp回調(diào)函數(shù)名的參數(shù)名(一般默認(rèn)為:callback)
jsonpCallback: "aehyok", //自定義的jsonp回調(diào)函數(shù)名稱,默認(rèn)為jQuery自動(dòng)生成的隨機(jī)函數(shù)名,也可以寫"?",jQuery會(huì)自動(dòng)為你處理數(shù)據(jù)
success: function (json) {
alert("第二次"+json.result);
},
error: function () {
alert('fail');
}
});
});
function aehyok(data) {
alert("第一次"+data.result);
}
</script>
我是在asp.net mvc3.0項(xiàng)目中,所以后臺(tái)在控制器中
public string aehyok()
{
return "aehyok({\"result\":\"我是遠(yuǎn)程js帶來(lái)的數(shù)據(jù)\"})";
}
然后執(zhí)行結(jié)果為

通過(guò)調(diào)試可以發(fā)現(xiàn)URLhttp://localhost:6247/Home/aehyok?callback=aehyok&_=1369235398641
callback=aehyok就是回調(diào)函數(shù),在調(diào)用完后臺(tái)返回是先執(zhí)行aehyok(data)。
然后又執(zhí)行success(json)。所以有兩次的彈窗。
我現(xiàn)在只不過(guò)是在一個(gè)項(xiàng)目下進(jìn)行,其實(shí)道理還是一樣的。
- js跨域問題之跨域iframe自適應(yīng)大小實(shí)現(xiàn)代碼
- jquery下利用jsonp跨域訪問實(shí)現(xiàn)方法
- 跨域請(qǐng)求之jQuery的ajax jsonp的使用解惑
- JS跨域總結(jié)
- 說(shuō)說(shuō)JSON和JSONP 也許你會(huì)豁然開朗
- 滑輪滾動(dòng)到頁(yè)面底部ajax加載數(shù)據(jù)配合jsonp實(shí)現(xiàn)探討
- 用jQuery與JSONP輕松解決跨域訪問的問題
- js跨域問題淺析及解決方法優(yōu)缺點(diǎn)對(duì)比
- 使用jsonp完美解決跨域問題
- 5種處理js跨域問題方法匯總
- js實(shí)現(xiàn)跨域的4種實(shí)用方法原理分析
相關(guān)文章
辨析JavaScript中的Undefined類型與null類型
Undefined與null都是js中的基本數(shù)據(jù)類型,然而正如它們的名字那樣,未初始化和空并不相同,下面我們就來(lái)詳細(xì)辨析JavaScript中的Undefined類型與null類型:2016-05-05JavaScript操作HTML DOM節(jié)點(diǎn)的基礎(chǔ)教程
這篇文章主要介紹了JavaScript操作HTML DOM節(jié)點(diǎn)的基礎(chǔ)入門教程,包括對(duì)節(jié)點(diǎn)的創(chuàng)建修改刪除等操作,還特別提到了其中appendChild()與insertBefore()插入節(jié)點(diǎn)時(shí)需注意的問題,需要的朋友可以參考下2016-03-03javascript中實(shí)現(xiàn)兼容JAVA的hashCode算法代碼分享
這篇文章主要介紹了javascript中實(shí)現(xiàn)兼容JAVA的hashCode算法代碼分享,實(shí)現(xiàn)跟JAVA中的運(yùn)算結(jié)果一致,需要的朋友可以參考下2014-08-08javascript中interval與setTimeOut的區(qū)別示例介紹
這篇文章主要介紹了javascript中interval與setTimeOut的區(qū)別,需要的朋友可以參考下2014-03-03詳解JavaScript中循環(huán)控制語(yǔ)句的用法
這篇文章主要介紹了詳解JavaScript中循環(huán)控制語(yǔ)句的用法,包括break語(yǔ)句和continue語(yǔ)句的使用方法,需要的朋友可以參考下2015-06-06