JSONP

在一個(gè)head標(biāo)簽中我們可以這么寫(xiě)

<script>
var callback = function(data){
      console.log(data);
  }
callback({name:'王柯智',age:'18'})
// 在控制臺(tái)打印出 {name:'王柯智',age:'18'}
</script>

我們定義了一個(gè)函數(shù),然后我們又調(diào)用了這個(gè)函數(shù),接下來(lái)我們把調(diào)用函數(shù)這句話(huà)(callback({name:'王柯智',age:'18'}))放在同級(jí)目錄下的另外一個(gè)JS文件叫做jsonp.js文件中,接下來(lái)我們的head標(biāo)簽就可以這么寫(xiě)

<script>
var callback = function(data){
      console.log(data);
  }
</script>
<script src='./jsop.js'>
</script>

以上代碼跟第一次我們寫(xiě)的代碼效果一模一樣。但是我們是從引入外部的JS來(lái)調(diào)用我們自己定義的函數(shù)。
如果把這個(gè)外部js放在服務(wù)器上的話(huà),我們的script標(biāo)簽可以會(huì)變成這種形式:

<script src='http://xxx.com/jsonp.js'>
</script>

然后我們?cè)诜?wù)器的jsonp.js文件里可以把服務(wù)器的數(shù)據(jù)拿到JS當(dāng)中,也就是說(shuō)這里的JS是這么寫(xiě)的

callback({key1:'value',key2:'value2'})

由于我們可能會(huì)多次調(diào)用callback函數(shù),為了把每次調(diào)用的函數(shù)和函數(shù)調(diào)用后得到的結(jié)果對(duì)應(yīng)起來(lái),通常我們會(huì)為這個(gè)函數(shù)取一個(gè)隨機(jī)的名字,代碼實(shí)現(xiàn)如下:

var num = Math.floor(Math.random() * 100000) // num是一個(gè)1到10萬(wàn)隨機(jī)數(shù) 
window.callbackName = 'callback_' + num;  //給windou添加一個(gè)全局屬性callbackName
window[callbackName] = function(data){ 
    console.log(data);
  }

此時(shí)我們定義便有了一個(gè)callback便有了一個(gè)隨機(jī)的名字,但是問(wèn)題來(lái)了,由于我們定義的函數(shù)名是隨機(jī)的,我們自己都不知道如何調(diào)用,我們?cè)趺词狗?wù)器上的那個(gè)函數(shù)名變成我們的函數(shù)名呢?
JSONP給出了一個(gè)方法,即在你需要加載的js文件后面加上'?callback="你的函數(shù)名"',所以我們的script標(biāo)簽便需要這樣寫(xiě):

<script src='http://xxx.com/jsopn.js?callback='+callbackName>

這樣我們就能把服務(wù)器上的函數(shù)名callback改成我們這里定義的函數(shù)名了。

可是還有個(gè)問(wèn)題,我們使用了2個(gè)script標(biāo)簽,一般來(lái)說(shuō),第二個(gè)script我們需要他動(dòng)態(tài)加載,所以我們只需要使用一個(gè)scirpt標(biāo)簽:

<script>

var num = Math.floor(Math.random() * 100000) // num是一個(gè)1到10萬(wàn)隨機(jī)數(shù) 
window.callbackName = 'callback_' + num;  //給windou添加一個(gè)全局屬性callbackName
window[callbackName] = function(data){ 
    console.log(data);
  }
//定義我們自己的函數(shù),并給他賦予一個(gè)隨機(jī)的名字
var sc = document.create('script')
sc.src = 'http://xxx.com/jsopn.js?callback=' + callbackName;
sc.id = 'script_' + callbackName;
document.body.appendChild(sc);
// script標(biāo)簽只有添加到文檔當(dāng)中才會(huì)去請(qǐng)求資源。
document.getElementById(sc.id).remove();
//當(dāng)函數(shù)被調(diào)用以后得到了服務(wù)器端的數(shù)據(jù)便把script標(biāo)簽從文檔中移除.
</script>
以上便是JSONP的用法。

當(dāng)然,我們可以給callback不同的功能,比如上述代碼中我們callback的功能是打印出data,你也可以再寫(xiě)一個(gè)callback,比如里面的代碼是console.log('xxx')也是可以的,但是這樣的話(huà)你可能會(huì)重寫(xiě)一次上面的代碼,會(huì)顯得很麻煩,所以我們把JSONP封裝一下,變成下面這個(gè)樣子:

function jsonp(url,fn){
    var num = Math.floor(Math.random() * 100000);
    var callbackName = 'callback_' + num;
    window[callbackName] = fn;
    var sc = document.createElement('script');
    sc.src = url + '?callback=' + callbackName;
    sc.id = 'script_' + num;
    document.body.appendChild(sc);
    document.getElementById(sc.id).remove()
}

這樣,當(dāng)我們想用jsonp的方式獲取數(shù)據(jù)并且對(duì)數(shù)據(jù)進(jìn)行處理的話(huà)就可以直接運(yùn)行
jsonp('http://www.xxx.com/jsop.js',function(data){
console.log(data);
})

當(dāng)然,我們也推薦使用JQuery的封裝好的JSONP語(yǔ)法:

$.ajax({
  url:'http://www.xxx.com/jsonp.js',
  datatype:'jsonp',
  success:function(data){
      console.log(data);
  }
}
)

不過(guò)需要注意的是,雖然JQ這里寫(xiě)的是$.ajax,但是JSONP并不是Ajax,這樣寫(xiě)只是為了方便而把Ajax和JSONP的功能封裝在了一起,你在瀏覽器下打開(kāi)開(kāi)發(fā)者工具可以看到j(luò)sop的請(qǐng)求類(lèi)型不是xhr。

最后編輯于
?著作權(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)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 前言 說(shuō)到AJAX就會(huì)不可避免的面臨兩個(gè)問(wèn)題,第一個(gè)是AJAX以何種格式來(lái)交換數(shù)據(jù)?第二個(gè)是跨域的需求如何解決?這...
    蠟筆小噺沒(méi)有煩惱閱讀 1,674評(píng)論 4 43
  • 本文轉(zhuǎn)自,博客園,昵稱(chēng):[隨它去吧],http://www.cnblogs.com/dowinning/archi...
    戰(zhàn)神飄雪閱讀 974評(píng)論 0 6
  • 0. 前言 說(shuō)到AJAX就會(huì)不可避免的面臨兩個(gè)問(wèn)題。 AJAX以何種格式來(lái)交換數(shù)據(jù)? 第二個(gè)是跨域的需求如何解決?...
    公子七閱讀 23,787評(píng)論 7 67
  • 誕生背景: 由于A(yíng)jax直接請(qǐng)求普通文件存在跨域無(wú)權(quán)訪(fǎng)問(wèn)的問(wèn)題,甭管是靜態(tài)頁(yè)面、動(dòng)態(tài)網(wǎng)頁(yè)、web服務(wù)、wcf、只要...
    FTOLsXD閱讀 1,163評(píng)論 0 1
  • 什么是JSONP? 先說(shuō)說(shuō)JSONP是怎么產(chǎn)生的: 其實(shí)網(wǎng)上關(guān)于JSONP的講解有很多,但卻千篇一律,而且云里霧里...
    wanggs閱讀 452評(píng)論 0 2

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