1螃征、jsonp
最常見的一種跨域方式靖榕,其背后原理就是利用了 script 標(biāo)簽不受同源策略的限制挚躯,在頁(yè)面中動(dòng)態(tài)插入了 script忍捡,script 標(biāo)簽的 src 屬性就是后端 api 接口的地址,并且以 get 的方式將前端回調(diào)處理函數(shù)名稱告訴后端竖幔,后端在響應(yīng)請(qǐng)求時(shí)會(huì)將回調(diào)返還廊酣,并且將數(shù)據(jù)以參數(shù)的形式傳遞回去。
前端:
// http://127.0.0.1:8888/jsonp.html
var script = document.createElement('script');
script.src = 'http://127.0.0.1:2333/jsonpHandler?callback=_callback';
document.body.appendChild(script); //插入script標(biāo)簽
// 回調(diào)處理函數(shù) _callback
var _callback = function(obj) {
for(key in obj) {
console.log('key: ' + key +' value: ' + obj[key]);
}
}
后端:
// http://127.0.0.1:2333/jsonpHandler
app.get('/jsonpHandler', (req, res) => {
let callback = req.query.callback;
let obj = {
type: 'jsonp',
name: 'weapon-x'
};
res.writeHead(200, {"Content-Type": "text/javascript"});
res.end(callback + '(' + JSON.stringify(obj) + ')');
})
在 jsonp.html 中打開控制臺(tái)可以看到返回?cái)?shù)據(jù)的輸出:
2赏枚、CORS
Cross-Origin Resource Sharing(跨域資源共享)是一種允許當(dāng)前域(origin)的資源(比如html/js/web service)被其他域(origin)的腳本請(qǐng)求訪問(wèn)的機(jī)制亡驰。
當(dāng)使用 XMLHttpRequest 發(fā)送請(qǐng)求時(shí),瀏覽器如果發(fā)現(xiàn)違反了同源策略就會(huì)自動(dòng)加上一個(gè)請(qǐng)求頭 origin饿幅,后端在接受到請(qǐng)求后確定響應(yīng)后會(huì)在 Response Headers 中加入一個(gè)屬性 Access-Control-Allow-Origin凡辱,值就是發(fā)起請(qǐng)求的源地址(http://127.0.0.1:8888),瀏覽器得到響應(yīng)會(huì)進(jìn)行判斷 Access-Control-Allow-Origin 的值是否和當(dāng)前的地址相同栗恩,只有匹配成功后才進(jìn)行響應(yīng)處理透乾。
前端:
// http://127.0.0.1:8888/cors.html
var xhr = new XMLHttpRequest();
xhr.onload = function(data) {
var _data = JSON.parse(data.target.responseText)
for(key in _data) {
console.log('key: ' + key + ' value: ' + _data[key]);
}
};
xhr.open('POST','http://127.0.0.1:2333/cors',true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send();
后端:
// http://127.0.0.1:2333/cors
app.post('/cors', (req, res) => {
if(req.headers.origin) {
res.writeHead(200, {
"Content-Type": "text/html; charset=UTF-8",
"Access-Control-Allow-Origin": 'http://127.0.0.1:8888'
});
let people = {
type: 'cors',
name: 'weapon-x'
}
res.end(JSON.stringify(people));
}
})
可以在開發(fā)者工具里面看到請(qǐng)求的詳細(xì)信息,并且在控制臺(tái)也可以看到返回的數(shù)據(jù)輸出:
3磕秤、postmessage跨域
在 HTML5 中新增了 postMessage 方法乳乌,postMessage 可以實(shí)現(xiàn)跨文檔消息傳輸 Cross Document Messaging,IE8市咆,F(xiàn)irefox 3汉操,Opera 9,Chrome 3 和 Safari 4 都支持 postMessage蒙兰。
該方法可以通過(guò)綁定 window 的 message 事件來(lái)監(jiān)聽發(fā)送跨文檔消息傳輸內(nèi)容磷瘤。
使用 postMessage 實(shí)現(xiàn)跨域的話原理就類似于 jsonp芒篷,動(dòng)態(tài)插入 iframe標(biāo)簽,再?gòu)?iframe 里面拿回?cái)?shù)據(jù)
采缚,私認(rèn)為用作跨頁(yè)面通信更加適合