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