JSONP解決同源策略限制引起跨域問(wèn)題原理
同源策略的限制引起跨域問(wèn)題
為了解決跨域問(wèn)題,大家利用script標(biāo)簽請(qǐng)求src指向的資源不受同源策略限制的特性來(lái)進(jìn)行資源的請(qǐng)求,這種方式就是JSONP。
接口實(shí)現(xiàn)
我們可以利用script標(biāo)簽請(qǐng)求資源不受同源策略限制的特性,可以自己簡(jiǎn)單的封裝一個(gè)jsonp請(qǐng)求函數(shù)。
首先在js代碼中手動(dòng)創(chuàng)建script標(biāo)簽,把需要請(qǐng)求的資源放到src屬性上,然后把script標(biāo)簽加入到body標(biāo)簽里面,在解析html的過(guò)程中就會(huì)執(zhí)行,當(dāng)執(zhí)行完script并且請(qǐng)求到資源后,后端結(jié)果會(huì)以函數(shù)調(diào)用的的形式返回字符串類型的響應(yīng)結(jié)果,這個(gè)形式的具體結(jié)構(gòu)為函數(shù)名稱(函數(shù)實(shí)參),和平時(shí)我們?cè)谡{(diào)用函數(shù)時(shí)沒(méi)有區(qū)別,然后頁(yè)面就會(huì)執(zhí)行后端返回的函數(shù)。
這里有個(gè)問(wèn)題,頁(yè)面會(huì)調(diào)用后端返回的函數(shù),那么這個(gè)函數(shù)在哪里定義?
當(dāng)然是要在本地的js代碼里面定義這個(gè)函數(shù),然后等待后端傳遞的參數(shù),這個(gè)參數(shù)其實(shí)就是我們想要的返回結(jié)果。
// 簡(jiǎn)單寫(xiě)個(gè)序列化函數(shù),不要就結(jié)是否考慮全面
function stringify(params) {
let res = "";
if (!params || typeof params !== "object") {
throw new Error("請(qǐng)傳遞參數(shù)對(duì)象");
}
Object.keys(params).forEach((key) => {
res += `&${key}=${params[key]}`;
});
return res.slice(1);
}
function jsonp({ url, params }) {
return new Promise((resolve) => {
const callback = `jsonp_${Math.ceil(Math.random() * 10000)}`;
const script = document.createElement("script");
script.src = `${url}?${stringify({ callback, ...params })}`;
document.body.appendChild(script);
// 一般情況下,函數(shù)的定義放置在window對(duì)象上,否則在調(diào)用函數(shù)的時(shí)候會(huì)找不到定義的實(shí)現(xiàn)
window[callback] = function (data) {
if (window[callback]) {
delete window[callback];
}
document.body.removeChild(script);
resolve(data);
};
});
}發(fā)送JSONP請(qǐng)求
利用封裝的jsonp發(fā)起請(qǐng)求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>jsonp請(qǐng)求</title>
</head>
<body>
<button>點(diǎn)我就會(huì)biubiubiu地發(fā)送請(qǐng)求</button>
</body>
<script>
const button = document.querySelector("button");
button.onclick = function () {
jsonp({ url: "http://localhost:8888" }).then(console.log);
};
</script>
</html>服務(wù)端處理JSONP請(qǐng)求
jsonp請(qǐng)求需要服務(wù)端配合,約定查詢參數(shù)callback是在本地定義好的函數(shù),根據(jù)傳遞過(guò)來(lái)的callback返回其函數(shù)調(diào)用,并把數(shù)據(jù)通過(guò)實(shí)參的方式返回給客戶端。
const http = require("http");
const url = require("url");
const qs = require("querystring");
const server = http.createServer((req, res) => {
const { query } = url.parse(req.url);
const params = qs.parse(query);
if (params.callback) {
const data = `${params.callback}(${JSON.stringify({ a: 1, b: 2 })})`;
res.end(data);
}
});
server.listen(8888, () => {
console.log("server is listen 8888");
});以上就是JSONP解決同源策略限制引起跨域問(wèn)題原理的詳細(xì)內(nèi)容,更多關(guān)于JSONP同源策略跨域限制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Javascript實(shí)現(xiàn)簡(jiǎn)易導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)簡(jiǎn)易導(dǎo)航欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
drag-and-drop實(shí)現(xiàn)圖片瀏覽器預(yù)覽
chrome的drag and drop API,它能將本地的圖片放到瀏覽器中進(jìn)行預(yù)覽,猜想一下當(dāng)我們把圖片拖拽到瀏覽器里會(huì)發(fā)生什么事情,你的瀏覽器試圖打開(kāi)一個(gè)新的頁(yè)面并加載這個(gè)圖片。這篇文章給我們介紹drag-and-drop實(shí)現(xiàn)圖片瀏覽器預(yù)覽,需要的朋友可以參考下2015-08-08
js中通過(guò)split函數(shù)分割字符串成數(shù)組小例子
分割字符串成數(shù)組的方法有很多,不過(guò)使用最多的還是split函數(shù),接下來(lái)為大家介紹下它的具體使用方法,感興趣的朋友可以參考下2013-09-09
JavaScript獲取數(shù)組最后一個(gè)元素的3種方法以及性能
在開(kāi)發(fā)過(guò)程中,我們常常需要得到j(luò)s數(shù)組的最后一個(gè)數(shù)組元素,下面這篇文章主要給大家介紹了關(guān)于JavaScript獲取數(shù)組最后一個(gè)元素的3種方法以及性能,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
小程序跳轉(zhuǎn)到的H5頁(yè)面再跳轉(zhuǎn)回跳小程序的方法
這篇文章主要介紹了小程序跳轉(zhuǎn)到的H5頁(yè)面再跳轉(zhuǎn)回跳小程序的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
javascript模板方法模式和職責(zé)鏈模式實(shí)例分析
這篇文章主要介紹了javascript模板方法模式和職責(zé)鏈模式,結(jié)合實(shí)例形式較為詳細(xì)的分析了模板方法模式和職責(zé)鏈模式基本原理、實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2023-07-07
js實(shí)現(xiàn)一個(gè)省市區(qū)三級(jí)聯(lián)動(dòng)選擇框代碼分享
省市區(qū)三級(jí)聯(lián)動(dòng)在填寫(xiě)表單時(shí)有關(guān)地址這一塊顯得尤為重要,直接提高了用戶的填寫(xiě)速度與準(zhǔn)確度,接下來(lái)本文使用js代碼實(shí)現(xiàn)一個(gè),感興趣的你可以參考下希望可以幫助到你2013-03-03
javascript框架設(shè)計(jì)之瀏覽器的嗅探和特征偵測(cè)
這篇文章主要介紹了javascript框架設(shè)計(jì)之瀏覽器的嗅探和特征偵測(cè)的相關(guān)資料,需要的朋友可以參考下2015-06-06
讓JavaScript擁有類似Lambda表達(dá)式編程能力的方法
在前幾天的博文中我發(fā)布了一個(gè)可以自定義頁(yè)碼呈現(xiàn)方式的組件,有C#和JavaScript兩個(gè)版本。2010-09-09

