平時工做當中,也已經好久沒有用JSONP 來跨域請求了,現從新整理一下,寫出本身對 JSONP 的理解。若是寫的有不對的,請各位看官評論指出,感謝。
行文時,系統環境爲 macOS Mojave v10.14.5,開發工具爲 vscode 1.45.1,瀏覽器爲 Goolge Chrome 版本 81.0.4044.138 。 javascript
JSONP(JSON with Padding)是JSON的一種「使用模式」,可用於解決主流瀏覽器的跨域數據訪問的問題。html
這是引用了百度百科對 JSONP 的定義。筆者本身的理解是, JSONP 是一種利用瀏覽器 script 標籤的能力實現訪問跨域數據的小技巧。就是利用 script 標籤能訪問跨域資源的能力,利用 JSON 去填充返回內容,以達到跨域的目的。 前端
上文說到了,JSONP 解決了跨域問題。那啥是跨域呢,簡單說就是發起請求的網站與被請求的網站,它倆的協議、主機、端口不是徹底同樣的。表現就是,跨域時,請求是不會成功的。
JSONP 究竟是怎麼實現的呢,筆者的理解是,基於下面三點實現的:java
接下來就寫點代碼測試一下,並用大白話把過程描述一下。
用koa模擬服務端,代碼以下面試
const koa = require("koa");
const mount = require("koa-mount");
const app = new koa();
app.use(
mount("/jsonp", (ctx) => {
let callback = ctx.query.abc;
let javascriptFileText = ` console.log(1); ${callback}("這是服務端的內容"); `;
ctx.body = javascriptFileText;
})
);
app.listen(8123);
複製代碼
前端代碼以下json
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>client</title>
</head>
<body>
<script> function handler(res) { console.log(res) } window.addEventListener('load', () => { var url = 'http://127.0.0.1:8123/jsonp?abc=handler' var script = document.createElement('script'); script.src = url // 把script標籤塞入到文檔裏,就會發起請求 document.getElementsByTagName('head')[0].appendChild(script); }) </script>
</body>
</html>
複製代碼
筆者認爲的過程以下:跨域
console.log(1)
和一個函數調用,在這個調用裏傳入 "這是服務端的內容" 。對於服務端來講,這一段始終是字符串文本。console.log(1);handler("這是服務端的內容")
這樣的內容,而後瀏覽器 JS引擎 就把這段內容執行,能夠對應 eval() 理解。執行的時候,是處於 全局上下文 的。因此是能拿到 handler 這個函數的。而後呢,在 handler 裏就經過res拿到了服務端傳回給前端的內容。是否是很妙?!!我第一次用的時候,真的是眼前一亮,原來能夠這麼玩。handler(this)
,而後前端頁面裏拿到的就是 handler 函數執行上下文裏的 this 變量了,一樣,這樣寫沒有任何意義,只會被打而已。也能夠寫成 handler('name="服務端給的name"&age="服務端給的age"')
,這樣,經過 & 和 = 去切割獲取內容,這樣也很麻煩呀,因此最終你們都選擇傳 JSON 格式的內容,這是最方便獲取內容的方式。因此就叫 JSONP 。(這樣看來,是否是也能夠叫 callbackP 、 STRINGP 呢??) JSONP 這種技巧,如今(2020-06-01)已經不多有聽到有還在使用的。由於現代瀏覽器基本都支持了 CORS 標準,這可比只支持 GET 的 JSONP 強太多了。之後,筆者估計本身是不會用到 JSONP 了,這篇文章只是筆者看到有些公司在面試時,仍是會問 JSONP 的內容。因此就記錄一下。瀏覽器