想知道jsonp到底是怎么實(shí)現(xiàn)的烙懦?看我驱入,包教會(huì)!

不管你好不好氯析,反正我是番茄醬亏较。為啥要寫(xiě)這篇文章呢,因?yàn)槲蚁雽?xiě)掩缓。

看這個(gè)文章的你肯定是想學(xué)會(huì)jsonp吧(廢話)雪情,那遇到這個(gè)文章是你的福氣。我敢保證這是全網(wǎng)最容易看懂的文章你辣。當(dāng)然巡通,你如果不會(huì)寫(xiě)js,不懂什么叫跨域绢记,那就算了扁达。別勉強(qiáng)了,勉強(qiáng)是沒(méi)有幸福的(而且你也沒(méi)有學(xué)習(xí)jsonp實(shí)現(xiàn)方法的必要)蠢熄。

首先聲明跪解,這篇文章不涉及后臺(tái)代碼的具體實(shí)現(xiàn),關(guān)于后臺(tái)的部分只說(shuō)思路。

好啦叉讥,那我們開(kāi)課啦窘行!

總的實(shí)現(xiàn)思路

我這篇教程的結(jié)構(gòu)是總-分-總(瞎扯的,實(shí)際上是總-隨意-隨意-...-隨意)图仓。我們先來(lái)說(shuō)說(shuō)總的實(shí)現(xiàn)思路罐盔。

我們都知道由于“同源策略”(不懂啥是同源策略沒(méi)關(guān)系,反正你知道有跨域現(xiàn)象就行了)救崔,而導(dǎo)致我們跨域的ajax請(qǐng)求發(fā)送失敗惶看,瀏覽器報(bào)錯(cuò)。

但是呢script標(biāo)簽的src是沒(méi)有跨域一說(shuō)的六孵,也就是說(shuō)你可以隨便引用別的網(wǎng)站的js纬黎。這就是總的實(shí)現(xiàn)思路。如果不理解這一點(diǎn)劫窒,也不用往下看了本今,因?yàn)槟阋阅愕闹R(shí)儲(chǔ)備和理解能力不合適看這文章。

說(shuō)完總的實(shí)現(xiàn)思路主巍,我們來(lái)看具體怎么做吧冠息。

1:先忘記我們要實(shí)現(xiàn)jsonp

先忘了我們的目標(biāo),看一下我們需要完成jsonp而需要掌握的知識(shí)孕索。先理解了這些逛艰,才能理解jsonp的實(shí)現(xiàn)。

1.1:基礎(chǔ)的js代碼

我們?cè)陧?yè)面寫(xiě)個(gè)這樣的代碼:

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

運(yùn)行結(jié)果:

對(duì)于代碼和結(jié)果沒(méi)有異議吧檬果。為啥我要寫(xiě)這樣的函數(shù)瓮孙。我要說(shuō)明的是這樣一點(diǎn):后一個(gè)script標(biāo)簽里的代碼可以引用前一個(gè)script代碼里的函數(shù)(全局)唐断。老規(guī)矩选脊,理解了這點(diǎn)就繼續(xù)往下看。

1.2:script標(biāo)簽引用文本

我們?cè)趆tml里寫(xiě)這樣的代碼:

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

然后我們?cè)谕窂较滦陆ㄒ粋€(gè)a.txt脸甘。并且a.txt里的文本如下:

a();

然后我們?cè)趆tml里引用a.txt恳啥。完整的代碼如下:

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

刷新頁(yè)面,控制臺(tái)如下:

也就是說(shuō)txt里的代碼被執(zhí)行了丹诀。所以a函數(shù)才會(huì)被執(zhí)行钝的。我要說(shuō)明的是:scritpt標(biāo)簽引用的外部文件中的文本內(nèi)容會(huì)被當(dāng)成js來(lái)解析。

也就是說(shuō)相當(dāng)于是這樣的代碼:

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

1.3:后臺(tái)返回文本

如果我們的后臺(tái)給我們返回的不是數(shù)據(jù)铆遭,而是跟a.txt一樣的文本如下文本:

a();

如我們請(qǐng)求地址為:https://www.a.com/a硝桩。則我們此時(shí)的完整代碼為:

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

那可以預(yù)見(jiàn),最終的結(jié)果會(huì)與1.2一致枚荣。因?yàn)橐驳扔谑侨缦碌拇a:

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

小結(jié)

以上的東西只是需要完成jsonp要懂的知識(shí)碗脊。你理解了可以繼續(xù)往下看。先不要深究“這樣怎么能實(shí)現(xiàn)”的問(wèn)題橄妆。不要急衙伶,我后面會(huì)說(shuō)的祈坠。如果不理解上面的知識(shí)可以多看幾遍。能夠自己動(dòng)手實(shí)驗(yàn)最好矢劲。

2:再看看一般的ajax請(qǐng)求

我們一般的ajax請(qǐng)求赦拘,是后臺(tái)給我們一個(gè)請(qǐng)求地址,我們發(fā)送請(qǐng)求芬沉,然后后臺(tái)返回給我們json格式的信息躺同。例如我們要請(qǐng)求的地址是:

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

后臺(tái)應(yīng)該返回給我們的數(shù)據(jù)是:

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

也就是說(shuō)我們最終需要的是服務(wù)器把json格式的數(shù)據(jù)給我們。但是我們用1里說(shuō)的方法丸逸,雖然服務(wù)器能調(diào)用我們本地的函數(shù)笋籽,但是我們?cè)趺茨塬@取到數(shù)據(jù)呢?

那這樣椭员,我們把1.3的html代碼改成這樣:

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

服務(wù)器返回的文本改成這樣:

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

也就是相當(dāng)于這樣的代碼:

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

最終結(jié)果:

也就是說(shuō)我們獲取到了我們需要的數(shù)據(jù)车海。但是萬(wàn)一我們的function不叫a,或者原本叫a隘击,但是因?yàn)榉N種原因需要改名侍芝,這樣后臺(tái)也要跟著改代碼。這增加了溝通成本埋同,也增加了后臺(tái)的工作量州叠。并且可能每個(gè)接口你們都需要去溝通這個(gè)函數(shù)的名字。這是問(wèn)題呀凶赁!

3.解決函數(shù)名的問(wèn)題

用script標(biāo)簽里的src相當(dāng)于向服務(wù)器發(fā)送了get請(qǐng)求咧栗。

不管你理不理解上面這點(diǎn),記住就行了虱肄。既然是相當(dāng)于get請(qǐng)求致板,那就可以帶參。并且后臺(tái)也能獲得這個(gè)參數(shù)的值咏窿。

既然這樣那我們是不是跟后臺(tái)溝通好我們給所有用jsonp的請(qǐng)求弄個(gè)參數(shù)斟或,這個(gè)參數(shù)的值是我們本地的函數(shù)名。后臺(tái)直接給我們返回函數(shù)名然后參數(shù)為數(shù)據(jù)值就ok辣集嵌?不理解的話看下面的過(guò)程萝挤。

比如我們和后臺(tái)溝通好參數(shù)名叫balabala,那代碼就像下面這樣:

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

后臺(tái)收到了這個(gè)請(qǐng)求根欧,不再像之前那樣直接返回給我們a(...)怜珍。

因?yàn)槲覀円呀?jīng)說(shuō)好了,函數(shù)名不再是固定的a凤粗,而是balabala這個(gè)參數(shù)的值才是我們的函數(shù)名酥泛。

于是后臺(tái)去獲取balabala這個(gè)參數(shù)的值,獲取到的是xiaoMoXian。于是后臺(tái)返回給我們:

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

于是代碼就相當(dāng)于是:

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

最終結(jié)果與2相同揭璃。

小結(jié)

以上就是jsonp的實(shí)現(xiàn)過(guò)程晚凿。我們已經(jīng)完成了不用ajax來(lái)請(qǐng)求,而利用script標(biāo)簽src屬性的跨域特性瘦馍,來(lái)實(shí)現(xiàn)我們獲取數(shù)據(jù)的目的歼秽。

我來(lái)小結(jié)下我們用到的知識(shí)點(diǎn):

  1. ajax請(qǐng)求受同源策略的影響不能跨域。(問(wèn)題)
  2. script標(biāo)簽的src是可以跨域的情组,不受同源策略的影響燥筷。(總的方法)
  3. 后一個(gè)script標(biāo)簽里的代碼可以引用前一個(gè)script代碼里的函數(shù)。
  4. scritpt標(biāo)簽引用的外部文件中的文本內(nèi)容會(huì)被當(dāng)成js來(lái)解析院崇。(結(jié)合3可以獲取數(shù)據(jù))
  5. 用script標(biāo)簽里的src相當(dāng)于向服務(wù)器發(fā)送了get請(qǐng)求肆氓。(解決函數(shù)名的問(wèn)題)

看到這并且看懂就說(shuō)明你已經(jīng)差不多可以畢業(yè)了。因?yàn)槟阋呀?jīng)完全懂了jsonp怎么實(shí)現(xiàn)的底瓣⌒痪荆可是我們一般用jsonp好像沒(méi)這么麻煩呀,也不用專門去寫(xiě)個(gè)函數(shù)來(lái)給后臺(tái)調(diào)用捐凭,也不用去寫(xiě)script標(biāo)簽寫(xiě)src到我們的請(qǐng)求地址拨扶,也不用溝通什么參數(shù)名。哪像你說(shuō)的這么麻煩W鲁Α患民?

哈哈,我要加班啦垦梆。預(yù)知后事如何匹颤,請(qǐng)多點(diǎn)贊。贊夠多我就更托猩。

據(jù)量子力學(xué)得到印蓖,點(diǎn)贊這篇文章的人都會(huì)成為歐皇,從此過(guò)著開(kāi)心幸福的生活??站刑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末另伍,一起剝皮案震驚了整個(gè)濱河市鼻百,隨后出現(xiàn)的幾起案子绞旅,更是在濱河造成了極大的恐慌,老刑警劉巖温艇,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件因悲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡勺爱,警方通過(guò)查閱死者的電腦和手機(jī)晃琳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人卫旱,你說(shuō)我怎么就攤上這事人灼。” “怎么了顾翼?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵投放,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我适贸,道長(zhǎng)灸芳,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任拜姿,我火速辦了婚禮烙样,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蕊肥。我一直安慰自己谒获,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布壁却。 她就那樣靜靜地躺著究反,像睡著了一般。 火紅的嫁衣襯著肌膚如雪儒洛。 梳的紋絲不亂的頭發(fā)上精耐,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音琅锻,去河邊找鬼众羡。 笑死铛纬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播漾唉,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涩搓!你這毒婦竟也來(lái)了蛙紫?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荷辕,失蹤者是張志新(化名)和其女友劉穎凿跳,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體疮方,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡控嗜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骡显。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疆栏。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡曾掂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出壁顶,到底是詐尸還是另有隱情珠洗,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布若专,位于F島的核電站险污,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏富岳。R本人自食惡果不足惜蛔糯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窖式。 院中可真熱鬧蚁飒,春花似錦、人聲如沸萝喘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阁簸。三九已至爬早,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間启妹,已是汗流浹背筛严。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饶米,地道東北人桨啃。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像檬输,于是被迫代替她去往敵國(guó)和親照瘾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355