同源策略
瀏覽器出于安全策略的考慮,只允許與本域下的接口交互。
本域指:
- 同協(xié)議
- 同域名
- 同端口
跨域的幾種方式
1. JSONP
原理:利用html中script標簽的src請求可以跨域獲取資源,通過前端傳遞回調(diào)函數(shù),后端用回調(diào)函數(shù)包裹數(shù)據(jù)并返回給前端,最后再由前端調(diào)用函數(shù)獲取數(shù)據(jù)。
代碼示例
// 前端
<script>
var script = document.createElement('script');
script.src = 'http://127.0.0.1:8080/JSONP?callback=_callback';
document.body.appendChild(script);
document.body.removeChild(script)
// 回調(diào)函數(shù)
var _callback = function (obj) {
for (key in obj) { c
onsole.log('key: ' + key + ' value: ' + obj[key]);
}
}
</script>
//后端
var express = require('express')
var app = express()
const port = '8080'
app.get('/JSONP',(req,res,next) => {
let callback = req.query.callback
let obj ={
type:'jsonp',
name:'lee'
}
res.writeHead(200,{"Content-Type": "text/javascript"});
res.end(`${callback}(${JSON.stringify(obj)})`)
})
app.listen(port)
console.log(`服務器地址為: http://localhost:${port}`);
JSONP跨域需要后端有對應接口
2. CORS
介紹:跨域資源共享是一種當前域的資源被其他域訪問的機制
原理:當使用 XMLHttpRequest 發(fā)送請求時,瀏覽器如果發(fā)現(xiàn)違反了同源策略就會自動加上一個請求頭 origin,后端在接受到請求后確定響應后會在 Response Headers 中加入一個屬性 Access-Control-Allow-Origin,值就是發(fā)起請求的源地址,瀏覽器得到響應會進行判斷 Access-Control-Allow-Origin 的值是否和當前的地址相同,只有匹配成功后才可以拿到相應數(shù)據(jù)
通過Hostbuddy修改
127.0.0.1 a.com
啟動http-server,打開http://a.com:8081/CORS.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>cros</title>
</head>
<body>
</body>
<script>
let xhr = new XMLHttpRequest()
xhr.open('GET','http://a.com:8080/CROS',true)
xhr.send()
xhr.onload= function(){
console.log(xhr.status);
console.log(xhr.responseText);
}
</script>
</html>
而服務器啟動在來8080端口
app.get('/CROS',(req,res) => {
console.log('CROS');
let obj = {
type:'cros',
name:'lee'
}
res.writeHead(200,{
"Content-Type":"text/html;charset=UTF-8",
"Access-Control-Allow-Origin":'http://a.com:8081'
//"Access-Control-Allow-Origin":'http://127.0.0.1:8081'
// "Access-Control-Allow-Origin":'http://b.com:8081'
})
res.end(JSON.stringify(obj))
})
只有http://a.com:8081成功了,"Access-Control-Allow-Origin":*
查看瀏覽器origin
Request Header中
Origin: http://a.com:8081
與
Response Header中的
Access-Control-Allow-Origin: http://a.com:8081
一致
3. 降域
使用
例子:
http://a.lcb.com:8080/a.html
http://b.lcb.com:8080/b.html
父域名相同,只要使用
document.domain = 'lcb.com'
指定到父域,即可實現(xiàn)跨域
4. messagePost
父窗口
// http://a.com:8081/postMessage.html
<!-- 通過 iframe 嵌入子頁面 -->
<iframe src="http://a.com:8082/other-domain.html"
id="otherPage"></iframe>
<br/><br/>
<input type="text" id="message"><input type="button"
value="Send to child.com" onclick="sendIt()" />
<script type="text/JavaScript">
function sendIt(){
// 通過 postMessage 向子窗口發(fā)送數(shù)據(jù)
document.getElementById("otherPage").contentWindow
.postMessage(
document.getElementById("message").value,
"http://a.com:8082"
);
}
</script>
子窗口
// http://a.com:8082/other-domain.html
<body>
Web page from http://localhost:8082
<div id="content"></div>
</body>
<script type="text/JavaScript">
//event 參數(shù)中有 data 屬性,就是父窗口發(fā)送過來的數(shù)據(jù)
window.addEventListener("message", function( event ) {
// 把父窗口發(fā)送過來的數(shù)據(jù)顯示在子窗口中
document.getElementById("content").innerHTML+=event.data+"<br/>";
}, false );
</script>