1.首先需要知道什麼事跨域 瀏覽器從一個功能變數名稱的網頁去請求另一個功能變數名稱的資源時,功能變數名稱、埠、協議任一不同,都是跨域 出於瀏覽器的同源策略限制 同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同 源策略,則瀏覽器的正常功能可能都會受到影響 同源策略限制 ...
1.首先需要知道什麼事跨域
- 瀏覽器從一個功能變數名稱的網頁去請求另一個功能變數名稱的資源時,功能變數名稱、埠、協議任一不同,都是跨域
- 出於瀏覽器的同源策略限制
- 同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同 源策略,則瀏覽器的正常功能可能都會受到影響
- 同源策略限制內容有:
- Cookie、LocalStorage、IndexedDB 等存儲性內容
- DOM 節點
- AJAX 請求發送後,結果被瀏覽器攔截了
2.什麼是JSONP
- JSONP是JSON with Padding的略稱,JSONP為民間提出的一種跨域解決方案,通過客戶端的script標簽發出的請求方式
- 原理就是通過添加一個
<script>
標簽,向伺服器請求JSON數據,這樣不受同源政策限制。伺服器收到請求後,將數據放在一個callback回調函數中傳回來。比如axios。不過只支持GET請求且不安全,可能遇到XSS攻擊,不過它的好處是可以向老瀏覽器或不支持CORS的網站請求數據 - 服務端: 將服務端返回數據封裝到指定函數中返回 callback({返回數據})
- 客戶端: 不管是我們的script標簽的src還是img標簽的src,或者說link標簽的href他們沒有被同源策略所限制,比如我們有可能使用一個網路上的圖片,就可以請求得到;所以利用同源策略漏洞,將訪問地址放在下麵的標簽的路徑中,
<script src="www.baidu.com"> 、< img src=""/>、 <link href=""/>
來解決跨域的問題
3.JSONP簡單實現
node伺服器端代碼
const express = require('express')
const app = express()
const port = 3000
//路由配置
app.get("/user",(req,res)=>{
//1.獲取客戶端發送過來的回調函數的名字
let fnName = req.query.callback;
//2.得到要通過JSONP形式發送給客戶端的數據
const data = {name:'tom'}
//3.根據前兩步得到的數據,拼接出個函數調用的字元串
let result = `${fnName}({name:"tom"})`
//4.把上步拼接得到的字元串,響應給客戶端的<script> 標簽進行解析執行
res.send(result);
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
前端代碼
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSONP簡單實現</title>
</head>
<body>
<button id="btn">點擊發送請求</button>
<script>
function getJsonpData(data) {
console.log("獲取數據成功")
console.log(data) //{name:'tom'}
}
var btn = document.getElementById("btn");
btn.onclick = function () {
//創建script標簽
var script = document.createElement("script");
script.src = 'http://localhost:3000/user?callback=getJsonpData';
document.body.appendChild(script);
script.onload = function () {
document.body.removeChild(script)
}
}
</script>
</body>
</html>
4.結論
- 優點:
- 相容性比較好,可用於解決主流瀏覽器的跨域數據訪問的問題
- 不受到同源策略的限制,在請求完畢後可以通過調用 callback 的方式回傳結果
- 缺點:
- 僅支持get請求;
- 具有局限性,不安全,可能會受到XSS攻擊;
- 只支持跨域 HTTP 請求這種情況,不能解決不同域的兩個頁面之間如何進行 Javascript 調用的問題