想知道jsonp到底是怎麼實現的?看我,包教會!
不管你好不好,反正我是番茄醬。為啥要寫這篇文章呢,因為我想寫。
看這個文章的你肯定是想學會jsonp吧(廢話),那遇到這個文章是你的福氣。我敢保證這是全網最容易看懂的文章。當然,你如果不會寫js,不懂什麼叫跨域,那就算了。別勉強了,勉強是沒有幸福的(而且你也沒有學習jsonp實現方法的必要)。
首先宣告,這篇文章不涉及後臺程式碼的具體實現,關於後臺的部分只說思路。
好啦,那我們開課啦!
總的實現思路
我這篇教程的結構是總-分-總(瞎扯的,實際上是總-隨意-隨意-...-隨意)。我們先來說說總的實現思路。
我們都知道由於“同源策略”(不懂啥是同源策略沒關係,反正你知道有跨域現象就行了),而導致我們跨域的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屬性的跨域特性,來實現我們獲取資料的目的。
我來小結下我們用到的知識點:
- ajax請求受同源策略的影響不能跨域。(問題)
- script標籤的src是可以跨域的,不受同源策略的影響。(總的方法)
- 後一個script標籤裡的程式碼可以引用前一個script程式碼裡的函式。
- scritpt標籤引用的外部檔案中的文字內容會被當成js來解析。(結合3可以獲取資料)
- 用script標籤裡的src相當於向伺服器傳送了get請求。(解決函式名的問題)
看到這並且看懂就說明你已經差不多可以畢業了。因為你已經完全懂了jsonp怎麼實現的。可是我們一般用jsonp好像沒這麼麻煩呀,也不用專門去寫個函式來給後臺呼叫,也不用去寫script標籤寫src到我們的請求地址,也不用溝通什麼引數名。哪像你說的這麼麻煩!?
哈哈,我要加班啦。預知後事如何,請多點贊。贊夠多我就更。
或者加我微信給我發1塊錢紅包,眾籌到10元我就更(誰還沒個身價了 ̄へ ̄)。
相關文章
- Go Error 巢狀到底是怎麼實現的?GoError巢狀
- 包教包會ReduxRedux
- 50行不到實現Promise化的jsonpPromiseJSON
- JSONP 跨域原理及實現JSON跨域
- JavaScript中模擬實現jsonpJavaScriptJSON
- 簡單理解JSONP的定義及其實現JSON
- 簡單的實現jsonp跨域請求JSON跨域
- jsonp 的原理和採用 Promise API 的實現JSONPromiseAPI
- 『JVM』我不想知道我是怎麼來滴,我就想知道我是怎麼沒滴JVM
- 北京老男孩教育怎麼樣?看看我的故事!
- HashMap到底是怎麼put的?HashMap
- MVVM模式到底是什麼?實現原理剖析MVVM模式
- jquery 之 jsonp 與 laravel 實現跨域jQueryJSONLaravel跨域
- Nginx-包教包會-入門Nginx
- JSONP 是什麼JSON
- 看我如何用定值 Cookie 實現反爬Cookie
- 雲端計算到底是怎麼玩的?
- Go 中的 channel 怎麼實現的?Go
- 「Vue原始碼學習」你想知道Vuex的實現原理嗎?Vue原始碼
- 關於大資料到底是怎麼來的大資料
- v-model 是怎麼實現的?
- 微信直播是怎麼實現的?
- synchronized底層是怎麼實現的?synchronized
- 怎麼實現微服務的實時效能分析?微服務
- JVM的ServerSocket是怎麼實現的(上)JVMServer
- JVM的ServerSocket是怎麼實現的(下)JVMServer
- 為什麼jsonp不支援post的方法?JSON
- Spring Boot 到底是怎麼執行的,你知道嗎?Spring Boot
- Spring Boot到底是怎麼執行的,你知道嗎?Spring Boot
- commonJs、AMD、UMD、es6 到底是怎麼用的JS
- 重磅出擊!!春季小程式活動大作戰,看我怎麼玩??
- 怎麼實現深拷貝
- 怎麼實現iMessage群發
- 怎麼實現谷歌登入?谷歌
- JSONP的原理是什麼?解決什麼問題?JSON
- 和 koa 不同的 express 是怎麼實現Express
- Fish Redux中的Dispatch是怎麼實現的?Redux
- “使用者組”在 Linux 上到底是怎麼工作的?Linux