js處理跨域的方案之jsonp用法詳解
1. 引言
在實(shí)際開發(fā)中,數(shù)據(jù)都是后端返回的,那就需要前端調(diào)用后端的接口,來拿到數(shù)據(jù)
前端中調(diào)接口的方式一般有如下三種
- Ajax
- fecth
axios
這個(gè)是最常用的
涉及到調(diào)后端接口的話,后端的接口和前端肯定不在一個(gè)端口,甚至不在一個(gè) 域名下,這樣就會(huì)導(dǎo)致跨域
fetch('https://editor.csdn.net/md?not_checkout=1&spm=1011.2415.3001.6217&articleId=141032145')
因?yàn)檎?qǐng)求的主機(jī)地址 和 請(qǐng)求的地址, 協(xié)議端口域名都不一樣,所以導(dǎo)致了 跨域
2. 同源策略和跨域
同源策略
同源:協(xié)議、域名、端口,三者全部相同,才是同源。
同源策略是瀏覽器最核心也最基本的安全機(jī)制,它限制了來自不同源(即域、協(xié)議或端口)的文檔或腳本之間的交互操作。
具體來說,同源策略要求如果兩個(gè)頁(yè)面的協(xié)議、域名和端口均相同,則它們被視為同源,否則即為非同源。
根據(jù)同源策略,瀏覽器只允許當(dāng)前網(wǎng)頁(yè)與同一源下的其他資源進(jìn)行交互,包括讀取和修改。
換句話說,JavaScript腳本在一個(gè)源中加載的頁(yè)面只能與同一源中的頁(yè)面進(jìn)行通信,而無(wú)法直接對(duì)不同源的頁(yè)面進(jìn)行讀寫操作。
同源策略的主要目的是防止惡意網(wǎng)站竊取或篡改其他網(wǎng)站的敏感信息,從而保護(hù)用戶的隱私和安全。
跨域
協(xié)議、域名、端口,只要有一個(gè)的不同,就是跨域。
URL | 是否跨域 | 備注 |
---|---|---|
http://www.baidu.com/1.html 和 http://www.baidu.com/2.html | 否 | 協(xié)議端口域名一樣,即為同源 |
http://www.baidu.com/1.html 和 http://www.csdn.com/2.html | 是 | 域名不同 |
http://www.baidu.com:7000/1.html 和 http://www.baidu.com:8000/2.html | 是 | 端口不同 |
https://www.baidu.com/1.html 和 http://www.baidu.com/2.html | 是 | 協(xié)議不同 |
注意: localhost 和 127.0.0.1 也是構(gòu)成了跨域
3. html 存在的特殊情況
html 中 有以下幾個(gè)標(biāo)簽, 是可以引入與當(dāng)前頁(yè)面不同(跨域) 的地址的
- script標(biāo)簽
- img 標(biāo)簽
- link 標(biāo)簽
- video 標(biāo)簽
- audio 標(biāo)簽
- iframe 標(biāo)簽
4. JSONP
JSONP 其實(shí)是 跨域的一種解決方案 JSONP 全稱“JSON with Padding”,譯為“帶回調(diào)的 JSON”,它是 JSON 的一種使用模式。通過 JSONP 可以繞過瀏覽器的同源策略,進(jìn)行跨域請(qǐng)求。
jsonp 的本質(zhì)是:利用 script 標(biāo)簽的
src 屬性
不受跨域的影響 。
前端具體操作
- 在JS腳本中,先 定義一個(gè)
函數(shù)
用來處于后端返回的數(shù)據(jù) - 通過js 腳本,創(chuàng)建
script
標(biāo)簽,src
設(shè)置為后端接口地址,并且請(qǐng)求地址中加上 第一步定義的函數(shù)名稱
- 把這個(gè)
script
插入到DOM中,調(diào)用接口
后端具體操作
- 開啟一個(gè)接口服務(wù)
- 解析出來請(qǐng)求地址查詢參數(shù)中的
callback
的值 - 返回文本類型,格式是 callback的值(后端數(shù)據(jù)) 比如:abc([{name:”1"},{ name:“2” }])
服務(wù)器返回的內(nèi)容,必須是一段可執(zhí)行的 JavaScript 代碼,不能是其它內(nèi)容
前端代碼如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button>點(diǎn)擊調(diào)用接口</button> <script> function getUser(list) { console.log('user', list); // 創(chuàng)建一個(gè)新的空白的文檔片段 let fragment = document.createDocumentFragment(); list.forEach(item => { let div = document.createElement('div'); div.innerHTML = item.name; fragment.appendChild(div); }); document.body.appendChild(fragment); } document.querySelector('button').onclick = function () { // 1、創(chuàng)建script 標(biāo)簽 let scriptEl = document.createElement('script'); // 2、設(shè)置 src 地址,并且傳遞過去 處理返回?cái)?shù)據(jù)的函數(shù)名稱 scriptEl.src = 'http://127.0.0.1:8080/api/getUserList?callback=getUser'; // 3、插入到DOM document.body.appendChild(scriptEl); } </script> </body> </html>
后端代碼如下
const htpp = require("http"); const url = require("url"); const querystring = require("querystring"); const userList = [ { id: 1, name: "張三" }, { id: 2, name: "李四" }, { id: 3, name: "王五" }, ]; const server = htpp .createServer((req, res) => { const parsedUrl = url.parse(req.url); const queryParams = querystring.parse(parsedUrl.query); console.log(req.url, queryParams); if (req.url.split("?")[0] === "/api/getUserList") { res.end(`${queryParams.callback}(${JSON.stringify(userList)})`); } else { res.end("404 Not Found"); } }) .listen(8080);
5. JSONP優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 相對(duì)簡(jiǎn)單:容易實(shí)現(xiàn)
- 兼容性好:由于JSONP依賴于
script標(biāo)簽
,它可以在老舊的瀏覽器中工作,不需要現(xiàn)代瀏覽器支持的高級(jí)功能或API。
缺點(diǎn)
- 只支持get 請(qǐng)求
- 安全性不好
可以使用其他的跨域方案,并不一定非得使用JSONP
參考鏈接
到此這篇關(guān)于js處理跨域的方案之jsonp用法詳解的文章就介紹到這了,更多相關(guān)js處理跨域jsonp內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript+css+HTML實(shí)現(xiàn)移動(dòng)端輪播圖(含源碼)
這篇文章主要介紹了JavaScript+css+HTML實(shí)現(xiàn)移動(dòng)端輪播圖并含源碼的分享,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2022-01-01JavaScript中字符串相關(guān)的方法使用總結(jié)
這篇文章主要為大家詳細(xì)介紹了JavaScript中字符串相關(guān)的方法使用,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的小伙伴可以學(xué)習(xí)一下2023-08-08javascript制作sql轉(zhuǎn)換為stringBuffer的小工具
這篇文章主要介紹了javascript制作sql轉(zhuǎn)換為stringBuffer的小工具,使用方法很簡(jiǎn)單,吧寫好的sql語(yǔ)句只要格式化好之后放進(jìn)去就可以了,推薦給大家,有需要的小伙伴可以參考下。2015-04-04如何將一維度數(shù)組轉(zhuǎn)換成三維數(shù)組結(jié)構(gòu)
在開發(fā)過程中,可能會(huì)遇到需要將一維數(shù)組轉(zhuǎn)換為多維數(shù)組的情況,以滿足特定數(shù)據(jù)結(jié)構(gòu)的需求,文章介紹了如何將后端返回的一維列表數(shù)據(jù)通過編程方法轉(zhuǎn)換成三維數(shù)組結(jié)構(gòu),以適應(yīng)特定的UI展示需求,通過循環(huán)遍歷和數(shù)據(jù)重組的方式,可以有效地實(shí)現(xiàn)數(shù)組結(jié)構(gòu)的轉(zhuǎn)換2024-09-09Radio 單選JS動(dòng)態(tài)添加的選項(xiàng)onchange事件無(wú)效的解決方法
radio 單選JS動(dòng)態(tài)添加的選項(xiàng),onchange事件無(wú)效。使用delegate()函數(shù)可以解決該問題,具體解決方案大家通過本文詳細(xì)了解下2016-12-12JavaScript canvas基于數(shù)組生成柱狀圖代碼實(shí)例
這篇文章主要介紹了JavaScript canvas基于數(shù)組生成柱狀圖代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03JS+H5 Canvas實(shí)現(xiàn)時(shí)鐘效果
這篇文章主要為大家詳細(xì)介紹了JS+H5 Canvas實(shí)現(xiàn)時(shí)鐘效果,利用JavaScript和Canvas實(shí)現(xiàn)簡(jiǎn)單時(shí)鐘效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07JS檢測(cè)頁(yè)面中哪個(gè)HTML標(biāo)簽觸發(fā)點(diǎn)擊事件的方法
這篇文章主要介紹了JS檢測(cè)頁(yè)面中哪個(gè)HTML標(biāo)簽觸發(fā)點(diǎn)擊事件的方法,涉及javascript頁(yè)面元素事件響應(yīng)機(jī)制,需要的朋友可以參考下2016-06-06