json與jsonp區(qū)別淺析(json才是目的,jsonp只是手段)

一言以蔽之近上,json返回的是一串?dāng)?shù)據(jù)剔宪;而jsonp返回的是腳本代碼(包含一個(gè)函數(shù)調(diào)用);

JSON其實(shí)就是JavaScript中的一個(gè)對(duì)象戈锻,跟var obj={}在質(zhì)上完全一樣歼跟,只是在量上可以無(wú)限擴(kuò)展。簡(jiǎn)單地講格遭,json其實(shí)就是JavaScript中的對(duì)象(Object)和數(shù)組(Array,其實(shí)也是對(duì)象)這倆好基友在那兒你嵌我我嵌你地套上n多層留瞳,以此模擬出許多復(fù)雜的數(shù)據(jù)結(jié)構(gòu)拒迅。

json易于人閱讀和編寫(xiě),也易于機(jī)器解析和生成她倘,相對(duì)網(wǎng)絡(luò)傳輸速率較高璧微,功能型網(wǎng)站前后端往往要頻繁大量交換數(shù)據(jù),而json憑借其強(qiáng)大的表現(xiàn)力和高顏值漸漸地成為理想的前后端數(shù)據(jù)交換語(yǔ)言硬梁。那xml前輩呢前硫,我覺(jué)得應(yīng)該會(huì)像微軟的xp那樣功成身退。

同源(不懂同源策略的童鞋請(qǐng)自行百度)下的前后端數(shù)據(jù)交換格式確定使用json了荧止,那么問(wèn)題來(lái)了屹电,如果我想獲取別人網(wǎng)站上提供的數(shù)據(jù)腫么做到呢阶剑?也就是跨域讀取數(shù)據(jù)問(wèn)題(不要鉆牛角說(shuō)你不需要讀取其他網(wǎng)站的數(shù)據(jù),相信我危号,你早晚得需要)牧愁,json行不行呢?答案是No Way外莲,為什么呢猪半,因?yàn)閖son只是普通的文本格式,能讓你這樣就輕松拿到那服務(wù)端就沒(méi)有任何安全和保密性可言了偷线,這樣的話互聯(lián)網(wǎng)世界非亂套不可磨确,這個(gè)問(wèn)題那些牛X的規(guī)范制定者早就想到了,所以使用了同源策略來(lái)限制文件獲取声邦。最后的結(jié)果就是只有像img乏奥、script、iframe這類可以指定src屬性的標(biāo)簽有跨域獲取別人網(wǎng)站上數(shù)據(jù)(圖片翔忽,腳本英融,源文件其實(shí)都是數(shù)據(jù))的能力。比如:

<!--京東商品圖片-->
![](http://img30.360buyimg.com/jgsqproductsoa/jfs/t2407/323/1635505465/47386/f2d89d88/56615e00N7a475ee6.jpg)
<!--百度CDN-->
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>

看來(lái)直接獲取json是行不通了歇式,那有沒(méi)有其他方法能拿到數(shù)據(jù)呢驶悟?于是乎jsonp就這樣被聰明的開(kāi)發(fā)者給發(fā)現(xiàn)了,為什么說(shuō)是發(fā)現(xiàn)而不是發(fā)明呢材失,因?yàn)椴](méi)有涉及到任何新技術(shù)痕鳍,就像發(fā)現(xiàn)ajax一樣。

jsonp原理是這樣的龙巨,網(wǎng)站A需要獲取網(wǎng)站B的數(shù)據(jù)笼呆,網(wǎng)站B說(shuō)我給你們一個(gè)方法,【1. 你們使用<script src="http://www.B.com/open.js"></script>標(biāo)簽先獲取到open.js文件(網(wǎng)站B的責(zé)任)旨别,這里邊有你們需要的數(shù)據(jù)诗赌。2. 你們獲取數(shù)據(jù)后處理數(shù)據(jù)(總得處理數(shù)據(jù)吧)的方法名必須命名為foo(數(shù)據(jù)請(qǐng)求者的責(zé)任和義務(wù))】,這里相當(dāng)于B網(wǎng)站和請(qǐng)求獲取數(shù)據(jù)者之間建立了一個(gè)協(xié)議秸弛,要求請(qǐng)求者務(wù)必按照規(guī)則辦事铭若,如果請(qǐng)求者不能同時(shí)遵守上面兩條就不能按預(yù)期獲取數(shù)據(jù)。額..递览,這也算相當(dāng)于建立了一個(gè)潛規(guī)則吧
open.js內(nèi)容

foo({"name":"B","age":23});  //為什么不直接寫(xiě)成json數(shù)據(jù){"name":"B","age":23}呢叼屠,原因很簡(jiǎn)單,在js文件總得合乎js語(yǔ)法吧
//這也是為什么協(xié)議中明確規(guī)定處理數(shù)據(jù)的方法名必須命名為foo绞铃,因?yàn)锽網(wǎng)站是在假定請(qǐng)求者的腳本中已經(jīng)定義了數(shù)據(jù)處理方法foo的情況下返回?cái)?shù)據(jù)镜雨;
//不然就會(huì)報(bào)foo is not defined錯(cuò)誤

網(wǎng)站A腳本須有

function foo(data){
    console.log(data);
    //ToDo..  
}

啊儿捧!雖然拐了個(gè)彎荚坞,但數(shù)據(jù)總算得到了挑宠,網(wǎng)站A,網(wǎng)站B都非常高興西剥,那么問(wèn)題又來(lái)了痹栖,網(wǎng)站C說(shuō)也需要獲取網(wǎng)站B的數(shù)據(jù),網(wǎng)站B把協(xié)議甩給它瞭空,網(wǎng)站C拿過(guò)來(lái)一看揪阿,草泥馬啊,foo這個(gè)名字已經(jīng)在自己的腳本文件的6868行用過(guò)了咆畏,而且已經(jīng)使用在腳本的各個(gè)角落南捂,批量替換會(huì)導(dǎo)致很多潛在bug啊,網(wǎng)站B情急之下決定把foo改成fool旧找,網(wǎng)站A立馬蹦起來(lái)溺健,因?yàn)樽约旱木W(wǎng)站已經(jīng)在很多地方使用foo引用了數(shù)據(jù)。

為了避免上面情況發(fā)生钮蛛,那些牛X哄哄的開(kāi)發(fā)者使用了動(dòng)態(tài)生成js文件的方法鞭缭,php版本如下:

open.php

<?php
header('Content-type: application/javascript');
$jsonCallback = htmlspecialchars($_REQUEST ['callback']);    //獲取請(qǐng)求者自定義的回調(diào)函數(shù)名
$jsonData ='{"name":"B","age":23}';    //待返回的json數(shù)據(jù)
echo $jsonCallback . "(" . $jsonData . ")";    //輸出jsonp格式的數(shù)據(jù),即一行函數(shù)調(diào)用語(yǔ)句
?>

額 ..魏颓,至于php為什么能返回js格式文件岭辣,自行百度。
于是網(wǎng)站A用<script src="http://www.B.com/open.php?callback=foo"></script>來(lái)請(qǐng)求數(shù)據(jù)甸饱,不需要修改任何變量沦童,返回給A的腳本文件內(nèi)容是:

foo({"name":"B","age":23});  //所謂的jsonp,就是一句函數(shù)調(diào)用叹话,數(shù)據(jù)都被包裹傳遞到參數(shù)中了偷遗,千萬(wàn)別穿個(gè)馬甲就不認(rèn)識(shí)了

網(wǎng)站C就用<script src="http://www.B.com/open.php?callback=blah"></script>來(lái)請(qǐng)求數(shù)據(jù),返回給C的腳本文件內(nèi)容是:

blah({"name":"B","age":23});

網(wǎng)站N就用<script src="http://www.B.com/open.php?callback=what"></script>來(lái)請(qǐng)求數(shù)據(jù)驼壶,返回給N的腳本文件內(nèi)容是:

what({"name":"B","age":23});

Problem Solved氏豌,大家都取到了期望的數(shù)據(jù),并且避免了命名沖突热凹。

jsonp全名叫做json with padding箩溃,很形象,就是把json對(duì)象用符合js語(yǔ)法的形式包裹起來(lái)以使其它網(wǎng)站可以請(qǐng)求得到碌嘀,也就是將json數(shù)據(jù)封裝成js文件;

json是理想的數(shù)據(jù)交換格式歪架,但沒(méi)辦法跨域直接獲取股冗,于是就將json包裹(padding)在一個(gè)合法的js語(yǔ)句中作為js文件傳過(guò)去。這就是json和jsonp的區(qū)別和蚪,json是想要的東西止状,jsonp是達(dá)到這個(gè)目的而普遍采用的一種方法烹棉,當(dāng)然最終獲得和處理的還是json。所以說(shuō)json是目的怯疤,jsonp只是手段浆洗。json總會(huì)用到,而jsonp只有在跨域獲取數(shù)據(jù)才會(huì)用到集峦。

理解了json和jsonp的區(qū)別之后伏社,其實(shí)ajax里的跨域獲取數(shù)據(jù)就很好理解和實(shí)現(xiàn)了,同源時(shí)候并沒(méi)有什么特別的塔淤,直接取就行摘昌,跨域時(shí)候需要拐個(gè)彎來(lái)達(dá)到目的。

附上jquery中ajax請(qǐng)求json數(shù)據(jù)實(shí)例:

(同源):

$.ajax({
    url:"persons.json",
    success:function(data){
    console.log(data);
     //ToDo..
  }
});

(跨域)

$.ajax({
    url:"http://www.B.com/open.php?callback=?",
    dataType:"jsonp",
    success:function(data){
        console.log(data);
        //ToDo..
    }
});   

jquery已把jsonp封裝進(jìn)ajax高蜂,很合理聪黎,因?yàn)楫吘菇^大多數(shù)的jsonp請(qǐng)求都是ajax,關(guān)于jquery的ajax具體用法請(qǐng)自行百度备恤,另外要注意的一點(diǎn)就是不同的網(wǎng)站提供的數(shù)據(jù)接口的$_REQUEST ['callback']中不一定絕對(duì)是callback也可能是cb,cbk等稿饰,具體使用時(shí)務(wù)必閱讀服務(wù)端提供的有關(guān)接口使用的詳細(xì)文檔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末露泊,一起剝皮案震驚了整個(gè)濱河市喉镰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滤淳,老刑警劉巖梧喷,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異脖咐,居然都是意外死亡铺敌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)屁擅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)偿凭,“玉大人,你說(shuō)我怎么就攤上這事派歌⊥淠遥” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵胶果,是天一觀的道長(zhǎng)匾嘱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)早抠,這世上最難降的妖魔是什么霎烙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上悬垃,老公的妹妹穿的比我還像新娘游昼。我一直安慰自己,他們只是感情好尝蠕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布烘豌。 她就那樣靜靜地躺著,像睡著了一般看彼。 火紅的嫁衣襯著肌膚如雪廊佩。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天闲昭,我揣著相機(jī)與錄音罐寨,去河邊找鬼。 笑死序矩,一個(gè)胖子當(dāng)著我的面吹牛鸯绿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播簸淀,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瓶蝴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了租幕?” 一聲冷哼從身側(cè)響起舷手,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎劲绪,沒(méi)想到半個(gè)月后男窟,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贾富,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年歉眷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颤枪。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡汗捡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出畏纲,到底是詐尸還是另有隱情扇住,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布盗胀,位于F島的核電站艘蹋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏票灰。R本人自食惡果不足惜簿训,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一咱娶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧强品,春花似錦、人聲如沸屈糊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)逻锐。三九已至夫晌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昧诱,已是汗流浹背晓淀。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盏档,地道東北人凶掰。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蜈亩,于是被迫代替她去往敵國(guó)和親懦窘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容