想知道jsonp究竟是怎麼實現的?看我,包教會!

無論你好很差,反正我是番茄醬。爲啥要寫這篇文章呢,由於我想寫。javascript

看這個文章的你確定是想學會jsonp吧(廢話),那遇到這個文章是你的福氣。我敢保證這是全網最容易看懂的文章。固然,你若是不會寫js,不懂什麼叫跨域,那就算了。別勉強了,勉強是沒有幸福的(並且你也沒有學習jsonp實現方法的必要)。html

首先聲明,這篇文章不涉及後臺代碼的具體實現,關於後臺的部分只說思路。java

好啦,那咱們開課啦!ajax

總的實現思路

我這篇教程的結構是總-分-總(瞎扯的,其實是總-隨意-隨意-...-隨意)。咱們先來講說總的實現思路。json

咱們都知道因爲「同源策略」(不懂啥是同源策略不要緊,反正你知道有跨域現象就好了),而致使咱們跨域的ajax請求發送失敗,瀏覽器報錯。跨域

可是呢script標籤的src是沒有跨域一說的,也就是說你能夠隨便引用別的網站的js。這就是總的實現思路。若是不理解這一點,也不用往下看了,由於你以你的知識儲備和理解能力不合適看這文章。瀏覽器

說完總的實現思路,咱們來看具體怎麼作吧。服務器

1:先忘記咱們要實現jsonp

先忘了咱們的目標,看一下咱們須要完成jsonp而須要掌握的知識。先理解了這些,才能理解jsonp的實現。微信

1.1:基礎的js代碼

咱們在頁面寫個這樣的代碼:函數

<script>
    function a() {
        console.log('hello cat!');
    }
</script>
<script>
    a();
</script>

運行結果:

對於代碼和結果沒有異議吧。爲啥我要寫這樣的函數。我要說明的是這樣一點:後一個script標籤裏的代碼能夠引用前一個script代碼裏的函數(全局)。老規矩,理解了這點就繼續往下看。

1.2:script標籤引用文本

咱們在html裏寫這樣的代碼:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>

而後咱們在同路徑下新建一個a.txt。而且a.txt裏的文本以下:

a();

而後咱們在html裏引用a.txt。完整的代碼以下:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>
<script src="a.txt"></script>

刷新頁面,控制檯以下:

也就是說txt裏的代碼被執行了。因此a函數纔會被執行。我要說明的是:scritpt標籤引用的外部文件中的文本內容會被當成js來解析。

也就是說至關因而這樣的代碼:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>
<script>
    a();
</script>

1.3:後臺返回文本

若是咱們的後臺給咱們返回的不是數據,而是跟a.txt同樣的文本以下文本:

a();

如咱們請求地址爲:https://www.a.com/a。則咱們此時的完整代碼爲:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>
<script src="https://www.a.com/a"></script>

那能夠預見,最終的結果會與1.2一致。由於也等因而以下的代碼:

<script>
    function a() {
        console.log('hello cat2!');
    }
</script>
<script>
    a();
</script>

小結

以上的東西只是須要完成jsonp要懂的知識。你理解了能夠繼續往下看。先不要深究「這樣怎麼能實現」的問題。不要急,我後面會說的。若是不理解上面的知識能夠多看幾遍。可以本身動手實驗最好。

2:再看看通常的ajax請求

咱們通常的ajax請求,是後臺給咱們一個請求地址,咱們發送請求,而後後臺返回給咱們json格式的信息。例如咱們要請求的地址是:

https://www.a.com/userInfo (獲取用戶信息)

後臺應該返回給咱們的數據是:

{
  "name": "番茄醬",
  "wechat": "fan_qie_jiang666",
  "qq": "1164431166",
  "email": "1164431166@qq.com"
}

也就是說咱們最終須要的是服務器把json格式的數據給咱們。可是咱們用1裏說的方法,雖然服務器能調用咱們本地的函數,可是咱們怎麼能獲取到數據呢?

那這樣,咱們把1.3的html代碼改爲這樣:

<script>
    function a(res) {
        console.log(res);
    }
</script>
<script src="https://www.a.com/userInfo"></script>

服務器返回的文本改爲這樣:

a({
    "name": "番茄醬",
    "wechat": "fan_qie_jiang666",
    "qq": "1164431166",
    "email": "1164431166@qq.com"
});

也就是至關於這樣的代碼:

<script>
    function a(res) {
        console.log(res);
    }
</script>
<script>
    a({
        "name": "番茄醬",
        "wechat": "fan_qie_jiang666",
        "qq": "1164431166",
        "email": "1164431166@qq.com"
    });
</script>

最終結果:

也就是說咱們獲取到了咱們須要的數據。可是萬一咱們的function不叫a,或者本來叫a,可是由於種種緣由須要更名,這樣後臺也要跟着改代碼。這增長了溝通成本,也增長了後臺的工做量。而且可能每一個接口大家都須要去溝通這個函數的名字。這是問題呀!

3.解決函數名的問題

用script標籤裏的src至關於向服務器發送了get請求。

無論你理不理解上面這點,記住就好了。既然是至關於get請求,那就能夠帶參。而且後臺也能得到這個參數的值。

既然這樣那咱們是否是跟後臺溝通好咱們給全部用jsonp的請求弄個參數,這個參數的值是咱們本地的函數名。後臺直接給咱們返回函數名而後參數爲數據值就ok辣?不理解的話看下面的過程。

好比咱們和後臺溝通好參數名叫balabala,那代碼就像下面這樣:

<script>
    function xiaoMoXian(res) {
        console.log(res);
    }
</script>
<script src="https://www.a.com/userInfo?balabala=xiaoMoXian"></script>

後臺收到了這個請求,再也不像以前那樣直接返回給咱們a(...)。

由於咱們已經說好了,函數名再也不是固定的a,而是balabala這個參數的值纔是咱們的函數名。

因而後臺去獲取balabala這個參數的值,獲取到的是xiaoMoXian。因而後臺返回給咱們:

xiaoMoXian({
    "name": "番茄醬",
    "wechat": "fan_qie_jiang666",
    "qq": "1164431166",
    "email": "1164431166@qq.com"
});

因而代碼就至關因而:

<script>
    function xiaoMoXian(res) {
        console.log(res);
    }
</script>
<script>
    xiaoMoXian({
        "name": "番茄醬",
        "wechat": "fan_qie_jiang666",
        "qq": "1164431166",
        "email": "1164431166@qq.com"
    });
</script>

最終結果與2相同。

小結

以上就是jsonp的實現過程。咱們已經完成了不用ajax來請求,而利用script標籤src屬性的跨域特性,來實現咱們獲取數據的目的。

我來小結下咱們用到的知識點:

  1. ajax請求受同源策略的影響不能跨域。(問題)
  2. script標籤的src是能夠跨域的,不受同源策略的影響。(總的方法)
  3. 後一個script標籤裏的代碼能夠引用前一個script代碼裏的函數。
  4. scritpt標籤引用的外部文件中的文本內容會被當成js來解析。(結合3能夠獲取數據)
  5. 用script標籤裏的src至關於向服務器發送了get請求。(解決函數名的問題)

看到這而且看懂就說明你已經差很少能夠畢業了。由於你已經徹底懂了jsonp怎麼實現的。但是咱們通常用jsonp好像沒這麼麻煩呀,也不用專門去寫個函數來給後臺調用,也不用去寫script標籤寫src到咱們的請求地址,也不用溝通什麼參數名。哪像你說的這麼麻煩!?

哈哈,我要加班啦。預知後事如何,請多點贊。贊夠多我就更。

或者加我微信給我發1塊錢紅包,衆籌到10元我就更(誰還沒個身價了 ̄へ ̄)。

相關文章
相關標籤/搜索