
2015-08-31 &nbs¶¶≈p; |  >©™;發布者:梁國(guó)芳 &nbs§<p; | 查看≠λ<→(kàn):3320次
技(jì)術(shù)雜(zá)談由于Sencha Touch 2這(zhè)種開(kāi)發模式的≥↔(de)特性,基本決定了(le)它原生(shēng §)的(de)數(shù)據交互行(xíng)為(wèi)幾乎隻₩¶"能(néng)通(tōng)過AJAX來(lái)實現(x ↓iàn)。
當然了(le),通(tōng)過調用(yòng)強大(λ✔dà)的(de)PhoneGap插件(jiàn)然後打包,你(n→πǐ)可(kě)以實現(xiàn)100%的(de) So≈✘cket通(tōng)訊和(hé)本地(dì)數(sh÷↑♣©ù)據庫功能(néng),又(yòu)或者通(tεσ★"ōng)過HTML5的(de)WebSocket也(yě)可(kě)→$δ&以實現(xiàn)與服務器(qì)的(de)通(tōng)訊和(♣₽hé)服務端推功能(néng),但(dàn)這(zhè)兩種方式都(↓₹↑dōu)有(yǒu)其局限性,前者 需要(yào)PhoneGap支©↑↕>持,後者要(yào)求用(yòng)戶設備必須支持WebSoc₽≤"♦ket,因此都(dōu)不(bù)能(néng)算(suàn)是(shì)∞£γST2的(de)原生(shēng)解決方案,原↔$"₽生(shēng)的(de)隻有(yǒu)AJAX。
說(shuō)到(dào)AJAX就(jiù)會(huì)不(bù)可(kě≥>)避免的(de)面臨兩個(gè)問(wèn)題,第一(yī)個(gè)是(shì)AJAX以何種格式φ§"來(lái)交換數(shù)據?第二個(gè)是(shì)跨域的(de)需求如₽<↕>(rú)何解決?這(zhè)兩個(gè)問(wèn)題目前都(dōu∏σ')有(yǒu)不(bù)同的(de)解決方案,比如(rú)數(s"&≈εhù)據可(kě)以用(yòng)自(zì)定義字符串或者用(yòn↔₽g)XML來(lái)描述,跨域可(kě)以通(tōng)過服δ♠>↓務器(qì)端代理(lǐ)來(lái)解決。
但(dàn)到(dào)目前為(wèi)止最被推¶β∏崇或者說(shuō)首選的(de)方案還(hái)是(shì)$§ 用(yòng)JSON來(lái)傳數(shù)據,靠JSONPβ☆✘✔來(lái)跨域。而這(zhè)就(jiù)是(shì)本文(wén)将要♥★π↓(yào)講述的(de)內(nèi)容。
JSON和(hé)JSONP雖然隻有(yǒu)一(yī ≠)個(gè)字母的(de)差别,但(dàn)其實他(tā)們根本不(♥σ♥bù)是(shì)一(yī)回事(shì) 兒(ér):JSON是"¶≥(shì)一(yī)種數(shù)據交換格式,而JSONP是(sh∑®↓ì)一(yī)種依靠開(kāi)發人(rén)員(yuán)的(de)聰明(α"✘míng)才智創造出的(de)一(yī)種非官方跨域數(s↔→hù)據交互協議(yì)。我們拿(ná)最近(jìn)比>★ ♦較火(huǒ)的(de)諜戰片來(lái)打個(gè✔×↑α)比 方,JSON是(shì)地(dì)下(xià)黨們用(yòng)來(l☆ ≈ái)書(shū)寫和(hé)交換情報(bào)的(de× ×)“暗(àn)号”•×,而JSONP則是(shì)把用(yòng±£)暗(àn)号書(shū)寫的(de)情報(bào)傳遞給自(zì) ✔己同志(zhì)時(shí)使用(yòn×✔•g)的(de)接頭方式。看(kàn)到(dào)≠™≠♠沒?一(yī)個(gè)是(shì)描述εΩ₩<信息的(de)格 式,一(yī)個(gè)是(shì)信息傳遞雙方約定的(de)方法。
前面簡單說(shuō)了(le)一(yī)下(xià),✔>γγJSON是(shì)一(yī)種基于文(wén)本的(de)數(shù)據交₩≈¶✘換方式,或者叫做(zuò)數(shù)據描述格式,你(nε☆∏>ǐ)是(shì)否該選用(yòng)他(tā)首先肯定要(yà ¥♥o)關注它所擁有(yǒu)的(de)優點。
JSON的(de)優點:
1、基于純文(wén)本,跨平台傳遞極其簡單;
2、Javascript原生(shēng)支持,後∑♥™台語言幾乎全部支持;
3、輕量級數(shù)據格式,占用(yòng)字符數(shù)量極少(™∏β™shǎo),特别适合互聯網傳遞;
4、可(kě)讀(dú)性較強,雖然比不(bù)上(shà♥♣∏ng)XML那(nà)麽一(yī)目了(le)然,但(dàn"Ω)在合理(lǐ)的(de)依次縮進之後還(hái)÷¶&是(shì)很(hěn)容易識别的(de)☆≤≈¥;
5、容易編寫和(hé)解析,當然前提是(≥★δ€shì)你(nǐ)要(yào)知(zhī)道(dào)數(shù)據結構;
JSON的(de)缺點當然也(yě)有(yǒu),但(dàn)在作(zuò&€± )者看(kàn)來(lái)實在是(shì)無關緊要(yào)的(de♦&♠α)東(dōng)西(xī),所以不(bù)✘$再單獨說(shuō)明(míng)。
JSON的(de)格式或者叫規則:
JSON能(néng)夠以非常簡單的(de★ ' )方式來(lái)描述數(shù)據結構,XML能(néng)做(zu±↓±ò)的(de)它都(dōu)能(néng) ₩ '做(zuò),因此在跨平台方面兩者完全不(bù)分>♣(fēn)伯仲。
1、JSON隻有(yǒu)兩種數(shù)據類★∑λ型描述符,大(dà)括号{}和(hé)方括号[],其餘英文≤✘(wén)冒号:是(shì)映射符,英文(w ♣∏én)逗号,是(shì)分(fēn)隔符,英文(wén)雙引号"&↓∑quot;是(shì)定義符。
2、大(dà)括号{}用(yòng)來(lái)♣®≈描述一(yī)組“不(bù)同類型的(de)無序鍵值對σ"(duì)集合”(每個(gè)鍵值對(duì)可(k&φ≤★ě)以理(lǐ)解為(wèi)OOP的(de)屬性±≤¶描述),方括号[]用(yòng)來(lái)描述一∞♠(yī)組“相(xiàng) ≠$同類型的(de)有(yǒu)序數(shù)據集合”(可(kě)對₩✘♥(duì)應OOP的(de)數(shù)組)。
3、上(shàng)述兩種集合中若有(yǒu)多(duō)個(gè)子(zǐ)∏÷項,則通(tōng)過英文(wén)逗号,進行(xí£λng)分(fēn)隔。
4、鍵值對(duì)以英文(wén)冒号:進行(xíng)分(fē±n)隔,并且建議(yì)鍵名都(dōu)加上(shàng)英文(w₽>én)雙引号"",以便<'于不(bù)同語言的(de)解析。
5、JSON內(nèi)部常用(yòng)數(shù)據類€γα£型無非就(jiù)是(shì)字符串、數(shù)字、布爾、日(∞÷¥>rì)期、null 這(zhè)麽幾個(gèα♥↕),字符串必須用(yòng)雙引号引起來(lái),其餘的(d∑≈e)都(dōu)不(bù)用(yòng),日(✔ rì)期類型比較特殊,這(zhè)裡(lǐ)就(Ω✘₽♠jiù)不(bù)展開(kāi)講述了(le),隻是(®↕♦αshì)建議(yì)如(rú)果客戶端沒有(yǒu)按日(rì¶×§∑)期排序功能(néng)需求的(de)話(huà),那(nà)麽把日(rì)≤ β期 時(shí)間(jiān)直接作(zuδ÷σò)為(wèi)字符串傳遞就(jiù)好(hǎo),可(kě)以省去(qù)很∏™✔×(hěn)多(duō)麻煩。
JSON實例:
// 描述一(yī)個(gè)人(rén) var person = { "Name": "Bob&&♦♥↔quot;, "Age": 32, "Company": "IBM&q≠γuot;, "Engineer": true } // 獲取這(zhè)個(gè)人(rén)的(de)信息 var personAge = person.Age; // 描述幾個(gè)人(rén) var members = [ { "Name": "Bob≥≥β", "Age": 32, "Company": "I✘βBM", "Engineer": true }, { "Name": "John"₹$, "Age": 20, "Company": &α★§quot;Oracle", "Engineer": false }, { "Name": "Henry", "Age": 45, "Company": "Micro∞α'soft", "Engineer": false } ] // 讀(dú)取其中John的(de)公司名稱 var johnsCompany = members[1].Company; // 描述一(yī)次會(huì)議(yì) var conference = { "Conference": "Fαλ♠uture Marketing", "Date": "§δ;2012-6-1", "Address": "Beiji≈σng", "Members": [ { "Name": "B λ§↕ob", "Age": 32, "Company": "IBM&™¶ ☆quot;, "Engineer": true }, { "Name": "John"γ φσ;, "Age": 20, "Company": &q$uot;Oracle", "Engineer": false }, { "Name": "Henryβ×", "Age": 45, "Company": "Microsoft&"Ω$quot;, "Engineer": false } ] } // 讀(dú)取參會(huì)者Henry是(shì)否αα® 工(gōng)程師(shī) var henryIsAnEngineer = conference.Member≤±ε♥s[2].Engineer; 什(shén)麽¶♣是(shì)JSONP?
先說(shuō)說(shuō)JSONP是(shì₹≈↕)怎麽産生(shēng)的(de):
其實網上(shàng)關于JSONP的(de)講解有(yǒu)很(hěn)β↓多(duō),但(dàn)卻千篇一(yī≠βλ)律,而且雲裡(lǐ)霧裡(lǐ),對(duì)于很(hěn π¥)多(duō)剛接觸的(de)人(rén)來(£™lái)講理(lǐ)解起來(lái)有(yǒu)些(xiē)困難,小(xi$λǎo)可(kě)不(bù)才,試著(zhe)用(yòng)自(z★€≠≠ì)己的(de)方式來(lái)闡釋一(yī)φ↔下(xià)這(zhè)個(gè)問(wèn)題,看(kà∞™n)看(kàn)是(shì)否有(yǒu)幫助。
1、一(yī)個(gè)衆所周知(zhī)的(de)問(≠≠βwèn)題,Ajax直接請(qǐng)求普通(tōng)文(wé©ε★n)件(jiàn)存在跨域無權限訪問(wèn)的(de)問(wèn§∞♥β)題,甭管你(nǐ)是(shì)靜(jìng)态頁面、動态網頁、web≤'服務、WCF,隻要(yào)是(shì)跨域請(qǐng)求,一(yī)律不©&(bù)準;
2、不(bù)過我們又(yòu)發現(xiàn),Web頁面上ε≥$(shàng)調用(yòng)js文(wén)件÷≠β(jiàn)時(shí)則不(bù)受是(shì)否跨域的(de)影(yǐn↑←¶g)響(不(bù)僅如(rú)此,我們還(hái)§₽σ發現(xiàn)凡是(shì)擁有(yǒu)"src&qu÷Ωot;這(zhè)個(gè)屬性的(de)标簽都(dōu)擁有(yǒu)跨域的☆>"♣(de)能(néng)力,比如(rú)<sc≠ ript>、<img>、&∑∑lt;iframe>);
3、于是(shì)可(kě)以判斷,當前階段如(rú)果想通(tō↓ng)過純web端(ActiveX控件(jiàn)、服務端代理(lǐ)、$§屬于未來(lái)的(de)HTML5之Websocket等方λ♦式不(bù)算(suàn))跨域訪問(wèn)數(shù)據就(j≤∞iù)隻有(yǒu)一(yī)種可(kě∏∏∞)能(néng),那(nà)就(jiù)是(shì)在遠±↕★(yuǎn)程服務器(qì)上(shàng)設法把數(<γ©shù)據裝進js格式的(de)文(wén)件(jiàn)裡(lǐδ₽₹↑),供客戶端調用(yòng)和(hé)進一(yī)步處理(lǐ);
4、恰巧我們已經知(zhī)道(dào)有(yǒu)一(yī)種¥α叫做(zuò)JSON的(de)純字符數(shù)據格式可(kě)∏以簡潔的(de)描述複雜(zá)數(shù)據,更妙的(de)是(s©↓♥hì)JSON還(hái)被js原生(shēng)支持,所以在客戶端幾乎可≤✘™(kě)以随心所欲的(de)處理(lǐ)這(zhè)種₽δ®格式的(de)數(shù)據;
5、這(zhè)樣子(zǐ)解決方案就($♠jiù)呼之欲出了(le),web客戶端通(tōng)過¶₩與調用(yòng)腳本一(yī)模一(yī&♣Ω§)樣的(de)方式,來(lái)調用(yòng)跨域服務器(qì)上(s®→hàng)動态生(shēng)成的(de)js格式文(wén)件(☆'®πjiàn)(一(yī)般以JSON為(wèi)後綴)≥,顯而易見(jiàn),服務器(qì)之所以要( σ yào)動态生(shēng)成JSON文(wén)件(≤♦jiàn),目的(de)就(jiù)在于把客戶端需要(yào)的←₽α∑(de)數(shù)據裝入進去(qù)。×↓γ
6、客戶端在對(duì)JSON文(wén)件(jπ'iàn)調用(yòng)成功之後,也(yě)就(♣"≤jiù)獲得(de)了(le)自(zì)己所需的(de)數(s∑★hù)據,剩下(xià)的(de)就(jiù)γ β是(shì)按照(zhào)自(zì)己需求進行(xíng$§÷γ)處理(lǐ)和(hé)展現(xiàn)了 ≤'(le),這(zhè)種獲取遠(yuǎn)程數(shù)據的(de)方式看(∏λ♥♥kàn)起來(lái)非常像AJAX,但(dàn)γ<♥其實并不(bù)一(yī)樣。
7、為(wèi)了(le)便于客戶端使用(yòng)數(s"↕>hù)據,逐漸形成了(le)一(yī)種非正式傳輸協議(yì♥↔),人(rén)們把它稱作(zuò) JSONP,該協議(yì)的(σ♦de)一(yī)個(gè)要(yào)點就("&α•jiù)是(shì)允許用(yòng)戶傳遞一(yī)個∑↕∏λ(gè)callback參數(shù)給服務端,然後服務端返回數(shù)據$$時(shí)會(huì)将這(zhè)個(gè)callb≤↓Ω↔ack參數(shù)作(zuò)為(wèi)函數(shù<♦)名來(lái)包裹住 JSON數(shù)據,這(zhè)樣客戶λ•端就(jiù)可(kě)以随意定制(zhì)自(zì)己♦Ω≈£的(de)函數(shù)來(lái)自(zì)動處理(lǐ)返回數(λσshù)據了(le)。
如(rú)果對(duì)于callback參數(shù)如(rú)何使用(y©∑òng)還(hái)有(yǒu)些(xiē)模糊的(d♦ &e)話(huà),我們後面會(huì)有(yǒu)具體(tǐ)的(™×de)實例來(lái)講解。
JSONP的(de)客戶端具體(tǐ)實現(xiàn):
不(bù)管jQuery也(yě)好(hǎo),extjs也(yě)★ 罷,又(yòu)或者是(shì)其他(tā)支持jsonp的π♠(de)框架,他(tā)們幕後所做(zuò)的(de♠β₹γ)工(gōng)作(zuò)都(dōu)是(shì)一(yī)樣的(deδ"♣),下(xià)面我來(lái)循序漸進的(de)說(shuō)明(m$✔πíng)一(yī)下(xià)jsonp在γπ客戶端的(de)實現(xiàn):
1、我們知(zhī)道(dào),哪怕跨域jsγ←文(wén)件(jiàn)中的(de)代碼(當然指符合web腳本安全策略的(→Ωde)),web頁面也(yě)是(shì)可(kě)以無條件(jiàn)執行→>φ(xíng)的(de)。
遠(yuǎn)程服務器(qì)remoteserver.c♠€δom根目錄下(xià)有(yǒu)個(gè)remote.js文(> wén)件(jiàn)代碼如(rú)下(xià):<₩
alert('我是(shì)遠(yuǎn)程文(×&©wén)件(jiàn)');
本地(dì)服務器(qì)localserver.com下(xià♦ε×)有(yǒu)個(gè)jsonp.html頁面代碼如(rú)下(xià):™
<!DOCTYPE html PUBLIC "<δ∏-//W3C//DTD XHTML 1.0 Transiti÷©γΩonal//EN" "http:$©✔//www.w3.org/TR/xhtml1/DTD/xhtml1-tra≤÷±nsitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&q₩↑∞uot;> <head> <title></title> <script type="text/javascript" src="http://remoteserver.co£" m/remote.js"></script> </head> <body> </body> </html>
毫無疑問(wèn),頁面将會(huì)彈出一(yī)個(gè)提•✔ ε示窗(chuāng)體(tǐ),顯示跨域調用(yòng)成功。
2、現(xiàn)在我們在jsonp.html頁面定義一(yī)個(gè)函♠₹ 數(shù),然後在遠(yuǎn)程re®€₩mote.js中傳入數(shù)據進行(xíng)調用(yòng)。
jsonp.html頁面代碼如(rú)下(xià):
<!DOCTYPE html PUBLIC "-//W3C//DTD Xδ¶HTML 1.0 Transitional//EN&©€×quot; "http://www.w3.org/"✘TR/xhtml1/DTD/xhtml1-transitional.dt <d"> <html xmlns="http://www.w3.org'>/1999/xhtml"> <head> <title></title> <script type="text/javascript"> var localHandler = function(data){ alert('我是(shì)本地(dì)函數(shù),可(kě)以被跨域的(de)rem£✔ote.js文(wén)件(jiàn)調用(yòng),遠♦≠≥(yuǎn)程js帶來(lái)的(de)數(shù)據是(shì)≈π:' + data.result); }; </script> <script type="text/javascript&€∞δquot; src="http://remoteserver.com/rem≤→αote.js"></script> </head> <body> </body> </html>
remote.js文(wén)件(jiàn¶↓ ®)代碼如(rú)下(xià):
localHandler({"result&β∏quot;:"我是(shì)遠(yuǎn)程js帶✔'λ來(lái)的(de)數(shù)據"↕÷★✔;});
運行(xíng)之後查看(kàn)結果,頁面成功彈出提示窗(c≤★huāng)口,顯示本地(dì)函數(shù)被跨域的(de)遠(yu♥≤ǎn)程js調用(yòng)成 功,并且還(hái)接ε©♥≈收到(dào)了(le)遠(yuǎn)程js帶來(lá✔ ₩→i)的(de)數(shù)據。很(hěn)欣喜,跨域遠(>≥yuǎn)程獲取數(shù)據的(de)目的(de)基本實α™ε↔現(xiàn)了(le),但(dàn)是(shì)又(yòu)一¶↑'(yī)個(gè)問(wèn)題出現(xiàn)了(le),我怎↓÷$麽讓遠(yuǎn)程js知(zhī)道(d♠≤ào)它應該調用(yòng)的(de)本地(dì)函數(shù)叫 什π(shén)麽名字呢(ne)?畢竟是(shì ≤>)jsonp的(de)服務者都(dōu)要(yào)面對(d♥₽®∑uì)很(hěn)多(duō)服務對(duì)象,而這(zhè)些(xiβ™☆πē)服務對(duì)象各自(zì)的(de)本地(dì)函數(shù)都™₩∑(dōu)不(bù)相(xiàng)同啊?我們接著(zhe)往下(xià)看£★(kàn)。
3、聰明(míng)的(de)開(kāi)發者很(hěn)容易想到(₩$↔dào),隻要(yào)服務端提供的(de)js腳本是(shì)動态生(s¥>®hēng)成的(de)就(jiù)行(xín↑"g)了(le)呗,這(zhè)樣調用(yòng)者可(kě)×$±π以傳一(yī)個(gè)參數(shù)過去(qù)告訴服務端&l±≤♥dquo;我想要(yào)一(yī)段調用(yòng)X∏♣↕←XX函數(shù)的(de)js代碼,請(qǐng)你(nǐ)返回給我&rα≥¶≥dquo;,于是(shì)服務器(qì)就ε∑δα(jiù)可(kě)以按照(zhào)客戶端的(de)需求來(lái≈€)生(shēng)成js腳本并響應了(lΩ>e)。
看(kàn)jsonp.html頁面的(de)代碼γ♣:
<!DOCTYPE html PUBLIC "-/δ©±≤/W3C//DTD XHTML 1.0 Tra¥&γ☆nsitional//EN" &quo<< t;http://www.w3.org/TR/xhtml1/D$÷©↔TD/xhtml1-transitional.dtd"↑™;> <html xmlns="http://www.w3.org/1999/xhtm±®σl"> <head> <title></title> <script type="text/javascript"> // 得(de)到(dào)航班信息查詢結果後的(de)回調函數€&(shù) var flightHandler = function(data){ alert(δ≥ '你(nǐ)查詢的(de)航班結果是(shì) ∞€≠:票(piào)價 ' + data.price + ' 元,' + '餘票(piào) ' + data.tickets + ' 張。'); }; // 提供jsonp服務的(de)url地(dì)址(不(bù)管是(shì)β∏什(shén)麽類型的(de)地(dì)址,最終生(shēng)成的(♣奕de)返回值都(dōu)是(shì)一(yī)段javascript代碼) var url = "http://flightQuery.com/j☆π♥sonp/flightResult.aspx?♣♣code=CA1998&callbac♣↕>k=flightHandler"; // 創建script标簽,設置其屬性 var script = document.createElement('script'); script.setAttribute('src', url); // 把script标簽加入head,此時(sh✔δ↕í)調用(yòng)開(kāi)始 document.getElementsByTagName(¶δ↑'head')[0].appendChild(script); </script> </head> <body> </body> </html>
這(zhè)次的(de)代碼變化(huà✘®¶)比較大(dà),不(bù)再直接把遠(y♥£"βuǎn)程js文(wén)件(jiàn)寫死,¥α←而是(shì)編碼實現(xiàn)動态查詢,而這(zhè)也(yě)£€↔正是(shì)jsonp客戶端實現(xià♠ δn)的(de)核心部分(fēn),本例中的(de)重點也(yΩ✘εě)就(jiù)在于如(rú)何完成jsonβ✔p調用(yòng)的(de)全過程。
我們看(kàn)到(dào)調用(yòng)的(de)url中β§¶傳遞了(le)一(yī)個(gè)cod≠λαe參數(shù),告訴服務器(qì)我要(≠>φyào)查的(de)是(shì)CA1998次航班的(de)信息€₹,而callback參數(shù)則告訴服務♣器(qì),我的(de)本地(dì)回調函數(shù)叫做(zu♣ φò)flightHandler,所以請(qǐng)把查 ↑φ×詢結果傳入這(zhè)個(gè)函數(shù↓ ≤<)中進行(xíng)調用(yòng)。
OK,服務器(qì)很(hěn)聰明(míng),這(zh" ★è)個(gè)叫做(zuò)flightResult.aspx的(de)頁面>•♥γ生(shēng)成了(le)一(yī)段這(zhè)♥←•®樣的(de)代碼提供給jsonp.html(服務端的(de)實現(φβxiàn)這(zhè)裡(lǐ)就(jiù≠±)不(bù)演示了(le),與你(nǐ)選用(yòng)的(de)語言無★✘關,說(shuō)到(dào)底就(jiù)是(shì)拼接字符串):
flightHandler({ "code": "CA1998"✘β∑, "price": 1780, "tickets":π ε 5 });
我們看(kàn)到(dào),傳遞給fli≥ε∞ghtHandler函數(shù)的(de)是(shì)一( ≈yī)個(gè)json,它描述了(le)航班的(de∏ε©)基本信息。運行(xíng)一(yī)下(xià)頁面,成功彈出提示窗(c§ <☆huāng)口,jsonp的(de)執行(xíng)全過程順利完成!
4、到(dào)這(zhè)裡(lǐ)為(wèi)♠α止的(de)話(huà),相(xiàng)信你×☆(nǐ)已經能(néng)夠理(lǐ)解jsonp的(de)客戶端實現(x♦™iàn)原理(lǐ)了(le)吧(ba)?剩下(xià)的(de)就₹®₽(jiù)是(shì)如(rú)何把代碼封裝一(yī)下(¶₩¥xià),以便于與用(yòng)戶界面交互,從↑×§÷(cóng)而實現(xiàn)多(duō)次和(hé)重複調用(yδ∞òng)。
什(shén)麽?你(nǐ)用(yòng)的(d≠φe)是(shì)jQuery,想知(zhī)道(dào)jQuery如(§γ∏rú)何實現(xiàn)jsonp調用(yòng)?好(hǎ∏↓o)吧(ba),那(nà)我就(jiù)好(hǎo)人≥>(rén)做(zuò)到(dào)底,再給你(nǐ)一(yī)段jQu×σ÷ery使用(yòng)jsonp的(de)代碼(我們依然沿用(yòng)上('α<shàng)面那(nà)個(gè)航班信息查詢的(de)例子(zǐ),假定返回Ω≈jsonp結果不(bù)變):
<!DOCTYPE html PUBLIC "-//W✘∑3C//DTD XHTML 1.0 Tra±πφnsitional//EN" &♦©quot;http://www.w3.org/TR/xhtml1/DTD→ ®/xhtml1-transitional.dtd"$↓∏ε> <html xmlns="http://www.w3.org/1999/xht§φφml" > <head> <title>Untitled Page</title> <script type="text/javascript" src=jquery.min.js"></script> <script type="text/javascript"> jQuery(document).ready(function(){
$.ajax({ t♠§ype: "get", async: false, url: "http://flightQuery.com/j₩↕"☆sonp/flightResult.aspx?code=CA199&σ≥8", dataType: "jsonp", jsonp: "callback",//傳遞給請(qǐng)求處理(lǐ)程序或頁面的(de),用(yòng)以獲得£πλ(de)jsonp回調函數(shù)名的(de)參數(shù)名($•β一(yī)般默認為(wèi):callback) jsonpCallback:"flightHandler",//自(zì)定義的(de)jsonp回調函• ™←數(shù)名稱,默認為(wèi)jQuery自Ωλ∞↕(zì)動生(shēng)成的(de)随機(✘£→jī)函數(shù)名,也(yě)可(kě)以β∞✔✔寫"?",jQuery會(huì)≈£€¶自(zì)動為(wèi)你(nǐ)處理(l€↓→↔ǐ)數(shù)據 success: function(json){ ™≈ alert('您查詢到(dào)航班信息:票(piào)價: ' + ©★json.price + ' 元,餘票(piàoσ±β§): ' + json.tickets + ' 張。'β¶♠); }, error: function(){ aleβλ< rt('fail'); } }); }); </script> </head> <body> </body> </html>
是(shì)不(bù)是(shì)有(y≤×✔←ǒu)點奇怪?為(wèi)什(shén)麽我這(zhè)次 ε沒有(yǒu)寫flightHandler這(✔✘δ♣zhè)個(gè)函數(shù)呢(ne)?而且竟然•®♠>也(yě)運行(xíng)成功了(le)!哈哈,這(zhè)就(j"∏iù)是(shì)jQuery的(de)功勞了(le),jquer→£♦y在處理(lǐ)jsonp類型的(de)ajax時(shí<∑)(還(hái)是(shì)忍不(bù)住吐槽,雖π♠然jquery也(yě)把jsonp歸入了(le)ajax,¥ε但(dàn)其實它們真的(de)不(bù)是(shì)一(yī)回事(sh★≥↓ì)兒(ér)),自(zì)動幫你(nǐ)生(§≤>♣shēng)成回調函數(shù)并把數(shù)據₹取出來(lái)供success屬性方法來(lái)調用(yòng),是(÷✘shì)不(bù)是(shì)很(hěn)爽呀?
1、ajax和(hé)jsonp這(zhè)兩種技(jì)術(sh←✔•ù)在調用(yòng)方式上(shàng)“看(kàn)起來(lái)&rdqu ∑←↕o;很(hěn)像,目的(de)也(yě)一(yī)樣,都(d λōu)是(shì)請(qǐng)求一(yī)個(gè)url,然後把服務•>$✘器(qì)返回的(de)數(shù)據進行(xí$♦ng)處理(lǐ),因此jquery和(hé)ext等框架都(dō>₹✔u)把jsonp作(zuò)為(wèi)ajax的(de)'ε一(yī)種形式進行(xíng)了(le♣♠♦)封裝;
2、但(dàn)ajax和(hé)jsonp其實本質上(shàng)是(sh✘σì)不(bù)同的(de)東(dōng)西(x)。ajax的(de)核心是(shì)通(tōng)過XmlHttpRe₹α₹πquest獲取非本頁內(nèi)容,而jsonp的(de)核心則是(shì∑ו )動态添加<script>标簽來(lái)調用(yòngφ₹)服務器(qì)提供的(de)js腳本。
3、所以說(shuō),其實ajax與jsonp的(de)區(qū)别& >不(bù)在于是(shì)否跨域,ajax通(tōngλ뱕)過服務端代理(lǐ)一(yī)樣可(kě)以實現(xià♠>£n)跨域,jsonp本身(shēn)也(yě)不(bù)排斥同域的(dα←₩ e)數(shù)據的(de)獲取。
4、還(hái)有(yǒu)就(jiù)是(sh∞γγì),jsonp是(shì)一(yī)種方式或者說(shuō)非強制>±(zhì)性協議(yì),如(rú)同ajax一(y¥✔≈÷ī)樣,它也(yě)不(bù)一(yī)定非要(yào)用(yòngγ∏<±)json格式來(lái)傳遞數(shù)據,如(rú)果你< (nǐ)願意,字符串都(dōu)行(xíng×"↕),隻不(bù)過這(zhè)樣不(bù)利于用(≥♥yòng)jsonp提供公開(kāi)服務。
總而言之,jsonp不(bù)是(shì)ajax的(de)一(yī)個(↓ ©gè)特例,哪怕jquery等巨頭把jsonp封裝進了(le)ajaγ¶δx,也(yě)不(bù)能(néng)改變著(zhe)一(yīΩ)點!
什(shén)麽是(shì)JSONP? 什(shén)麽是(shì)JSONP?
