[js一點(diǎn)也不難] JSONP是什么

一、JSONP的誕生

  • 首先,因?yàn)?lt;b>ajax</b>無(wú)法跨域,然后開發(fā)者就有所思考
  • 其次,開發(fā)者發(fā)現(xiàn),<b> <script></b>標(biāo)簽的<b>src</b>屬性是可以跨域的
  • 把跨域服務(wù)器寫成<b> 調(diào)用本地的函數(shù)</b> ,回調(diào)數(shù)據(jù)回來(lái)不就好了?
  • <b>json</b>剛好被js支持(<b>object</b>)
  • 調(diào)用跨域服務(wù)器上動(dòng)態(tài)生成的js格式文件(不管是什么類型的地址,最終生成的返回值都是一段js代碼
  • 這種獲取遠(yuǎn)程數(shù)據(jù)的方式看起來(lái)非常像ajax,但其實(shí)并不一樣
  • 便于客戶端使用數(shù)據(jù),逐漸形成了一種<b>非正式傳輸協(xié)議</b>,人們把它稱作<b>JSONP</b>。
  • 傳遞一個(gè)callback參數(shù)給跨域服務(wù)端,然后跨域服務(wù)端返回?cái)?shù)據(jù)時(shí)會(huì)將這個(gè)callback參數(shù)作為函數(shù)名來(lái)包裹住json數(shù)據(jù)即可。

二、老板,來(lái)一斤栗子。

【栗子一】

跨域服務(wù)器

文件:remote.js
代碼:

alert('我是遠(yuǎn)程文件');
本地
<script type="text/javascript" src="跨域服務(wù)器/remote.js"></script>

這邊做的就是直接引入一個(gè)js,頁(yè)面將會(huì)彈出一個(gè)提示窗體,顯示 我是遠(yuǎn)程文件。

【栗子二】

跨域服務(wù)器

文件:remote.js
代碼:

localHandler({"result":"我是遠(yuǎn)程js帶來(lái)的數(shù)據(jù)"});
本地
<script type="text/javascript"> 
    var localHandler = function(data){
        alert('我是本地函數(shù),可以被跨域的remote.js文件調(diào)用,遠(yuǎn)程js帶來(lái)的數(shù)據(jù)是:' + data.result); 
    }; 
</script> 
<script type="text/javascript" src="跨域服務(wù)器/remote.js"></script>

這邊做的是
1、本地定義一個(gè)函數(shù)
2、引入一個(gè)js
3、被引入的js里面,調(diào)用這個(gè)函數(shù)
頁(yè)面將會(huì)彈出一個(gè)提示窗體。顯示本地函數(shù)被跨域的遠(yuǎn)程js調(diào)用成功,并且還接收到了 我是遠(yuǎn)程js帶來(lái)的數(shù)據(jù)。

新問(wèn)題出現(xiàn)了:讓遠(yuǎn)程js知道它應(yīng)該調(diào)用的本地函數(shù)叫什么名字呢?畢竟是jsonp的服務(wù)者都要面對(duì)很多服務(wù)對(duì)象,而這些服務(wù)對(duì)象各自的本地函數(shù)都不相同???

【栗子三】

跨域服務(wù)端提供的js腳本動(dòng)態(tài)生成,這樣調(diào)用者可以傳一個(gè)參數(shù)過(guò)去告訴跨域服務(wù)端“我想要一段調(diào)用XXX函數(shù)的js代碼,請(qǐng)你返回給我”,于是跨域服務(wù)器就可以按照客戶端的需求來(lái)生成js腳本并響應(yīng)了。

跨域服務(wù)器

文件:flightResult.php
代碼:

flightHandler({
    "code":"CA1998",
    "price": 1780,
    "tickets": 5
}); 
本地
<script type="text/javascript"> 
    // 得到航班信息查詢結(jié)果后的回調(diào)函數(shù) 
    var flightHandler = function(data){
        alert('你查詢的航班結(jié)果是:票價(jià) ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 張。');
    }; 
    // 提供jsonp服務(wù)的url地址(不管是什么類型的地址,最終生成的返回值都是一段javascript代碼) 
    var url = "跨域服務(wù)器/flightResult.php?code=CA1998&callback=flightHandler";
    // 創(chuàng)建script標(biāo)簽,設(shè)置其屬性 
    var script = document.createElement('script'); 
    script.setAttribute('src', url); 
    // 把script標(biāo)簽加入head,此時(shí)調(diào)用開始 
    document.getElementsByTagName('head')[0].appendChild(script); 
</script>

這次我們做的是
1、動(dòng)態(tài)創(chuàng)建腳本
2、url中傳遞了一個(gè)code參數(shù),服務(wù)器去做查詢CA1998次航班的信息,callback參數(shù)告訴服務(wù)器,我的本地回調(diào)函數(shù)叫做flightHandler
3、跨域服務(wù)端調(diào)用這個(gè)函數(shù)flightHandler
頁(yè)面將會(huì)彈出一個(gè)提示窗體。把票價(jià)、余票以及張數(shù)給傳遞回來(lái)了。

三、那么服務(wù)器到底做了什么呢?

說(shuō)到底,就是拼接字符串。
// 數(shù)據(jù)
$data = [
    "name":"anonymous66",
    "age":"18",
    "like":"jianshu"
];
// 接收callback函數(shù)名稱
$callback = $_GET['callback'];
// 輸出
echo $callback . "(" . json_encode($data) . ")";

四、與AJAX的區(qū)別是什么?

ajax和jsonp本質(zhì)上是不同的東西。
ajax的核心是通過(guò)XmlHttpRequest獲取非本頁(yè)內(nèi)容
jsonp的核心則是動(dòng)態(tài)添加<script>標(biāo)簽來(lái)調(diào)用服務(wù)器提供的js腳本。

五、結(jié)語(yǔ)

本篇文章是對(duì)JSONP的原理掃盲,一般很多開發(fā)者會(huì)使用卻不知道原理,這在學(xué)習(xí)和成長(zhǎng)的路上不算好事。so,知道jsonp原理,你又可以加50塊工資了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容