一屋讶、同源策略
同源就是當(dāng)協(xié)議、域名和端口都一致時须教,才算是同源皿渗,有一個不同都不是同源。
同源策略官方解釋就是轻腺,限制從一個源加載的文檔或腳本如何與來自另一個源的資源進(jìn)行交互羹奉。這是一個用戶隔離潛在惡意文件的關(guān)鍵的安全機(jī)制。
不是同源约计,主要會有以下限制:
- cookie、LocalStorage和IndexDB無法讀取
- DOM無法獲取
- Ajax請求不能發(fā)送
二迁筛、前后端如何通信
- ① Ajax 煤蚌,受同源策略限制
- ② WebSocket耕挨,不受同源策略限制
- ③ CORS,既支持跨域通信尉桩,也支持同源通信
三筒占、如何創(chuàng)建Ajax
創(chuàng)建一個Ajax,主要考慮如下問題:
- XMLHttpRequest 對象的工作流程
- 兼容性的處理
- 事件的觸發(fā)條件
- 事件的觸發(fā)順序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function loadXMLDoc()
{
var xmlhttp;
var txt,x,i;
// 判斷XMLHttpRequest是否存在
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執(zhí)行代碼
xmlhttp=new XMLHttpRequest();
}
else
{
// IE6, IE5 瀏覽器執(zhí)行代碼
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
xmlDoc=xmlhttp.responseXML;
txt="";
x=xmlDoc.getElementsByTagName("ARTIST");
for (i=0;i<x.length;i++)
{
txt=txt + x[i].childNodes[0].nodeValue + "<br>";
}
document.getElementById("myDiv").innerHTML=txt;
}
}
xmlhttp.open("GET","cd_catalog.xml",true);
xmlhttp.send();
}
</script>
</head>
<body>
<h2>我收藏的 CD :</h2>
<div id="myDiv"></div>
<button type="button" onclick="loadXMLDoc()">獲取我的 CD</button>
</body>
</html>
創(chuàng)建一個Ajax的基本步驟:
- (1)創(chuàng)建XMLHttpRequest對象,也就是創(chuàng)建一個異步調(diào)用對象蜘犁。
- (2)創(chuàng)建一個新的HTTP請求,并指定請求的方法翰苫、URL、是否異步處理請求及驗(yàn)證信息这橙。
- (3)為onreadystatechange 事件綁定方法奏窑,監(jiān)聽狀態(tài)的改變。
- (4)發(fā)送HTTP請求屈扎。
四埃唯、跨域通信的幾種方式
- JSONP
只支持GET請求
利用script標(biāo)簽支持跨域的屬性,用script標(biāo)簽?zāi)玫桨藬?shù)據(jù)的方法(相當(dāng)于是返回了一段js代碼)鹰晨,在請求中包含callback墨叛,服務(wù)端注入?yún)?shù)后返回這個回調(diào)函數(shù),然后script標(biāo)簽?zāi)玫椒祷氐膉s代碼跨域直接運(yùn)行回調(diào)模蜡,需要前后端的配合漠趁。 - Hash
原理是利用location.hash來進(jìn)行傳值。在url: http://a.com#helloword中的‘#helloworld’就是location.hash忍疾,改變hash并不會導(dǎo)致頁面刷新闯传,所以可以利用hash值來進(jìn)行數(shù)據(jù)傳遞,當(dāng)然傳遞數(shù)據(jù)的大小是有限的膝昆。 - postMessage
// 窗口A(http://A.com)向跨域窗口B(http://B.com)發(fā)送信息
window.postMessage('data', 'http://B.com');
// 在窗口B中監(jiān)聽
window.addEventListener('message', function(event){
console.log(event.origin); // http://A.com
console.log(event.source); // A的window
console.log(event.data); // data
})
- WebSocket
特點(diǎn)包括:
(1)建立在 TCP 協(xié)議之上丸边,服務(wù)器端的實(shí)現(xiàn)比較容易。
(2)與 HTTP 協(xié)議有著良好的兼容性荚孵。默認(rèn)端口也是80和443妹窖,并且握手階段采用 HTTP 協(xié)議,因此握手時不容易屏蔽收叶,能通過各種 HTTP 代理服務(wù)器骄呼。
(3)數(shù)據(jù)格式比較輕量,性能開銷小判没,通信高效蜓萄。
(4)可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù)澄峰。
(5)沒有同源限制嫉沽,客戶端可以與任意服務(wù)器通信。
(6)協(xié)議標(biāo)識符是ws(如果加密俏竞,則為wss)绸硕,服務(wù)器網(wǎng)址就是 URL堂竟。
var ws = new Websocket('wss://echo.websocket.org');
ws.onopen = function(evt) {
console.log('Connection open...');
ws.send('Hello world!');
};
ws.onmessage = function (evt) {
console.log('Received Message' + evt.data);
ws.close();
};
ws.onclose = function (evt) {
console.log('Connection closed');
}
- CORS
為什么CORS能支持跨域通信?
瀏覽器會攔截Ajax請求玻佩,如果瀏覽器發(fā)現(xiàn)這個Ajax請求時跨域的出嘹,它會在HTTP請求頭中加一個origin。