同源策略(Same origin Policy)
-
解析
瀏覽器出于安全考慮,只允許與同域下的接口進行資源交互。
不同域的客戶端腳本在沒有明確授權的情況下雀久,不能讀寫對方的資源。 -
限制
不能通過ajax的方法去請求不同源中的文檔趁舀。
瀏覽器中不同域的框架之間是不能進行js的交互操作的赖捌。 -
同域
協議如 http
;
域名如 jirengu.com
矮烹;
端口如 80
越庇。
三者都相同才是同域。
跨域
-
解析
使不同域下的接口也能夠進行資源交互的一種技術奉狈。 - 實現方式
-
JSONP
(JSON with padding)
解析 一種使用JSON數據的方法
原理 利用<script>標簽沒有跨域限制卤唉,可以引入其他域下JS的特點;
過程
1 定義數據處理函數_fun
2 創(chuàng)建<script>仁期,src=后端接口桑驱,最后加個參數 callback=_fun
3 服務端在收到請求后,返還fun(data) 字符串
蟀拷。
4fun(data)
放在<script>做為js執(zhí)行碰纬。此時會調用fun函數,將data做為參數问芬。
Tip
1 只支持GET請求,不支持POST等其它類型的HTTP請求寿桨;
只支持跨域的HTTP請求此衅,不支持跨域的兩個頁面之間進行JS調用强戴。
2 不受同源策略影響;
兼容性較好挡鞍。
$('Btn').addEventListener('click', function(){
var script = document.createElement('script');
script.src = 'http://127.0.0.1/getNews?callback=done';
document.head.appendChild(script);
document.head.removeChild(script);
})
function done(data){
}
前端
-------------------------------------------------------------
后端
var cb = req.query.callback;
if(cb){
res.send(cb + '('+ JSON.stringify(data) + ')');
}else{
res.send(data);
} -
CORS
(Cross-origin resource sharing 跨域資源共享)
解析 一種 ajax 跨域請求資源的方式
原理 使用自定義的 HTTP 頭部骑歹,讓服務器與瀏覽器進行溝通。
過程
1 使用XMLHttpRequest
發(fā)送請求時墨微,瀏覽器會添加請求頭:Origin
2 后臺確定接受請求道媚,在返回結果中添加響應頭:Access-Control-Allow-Origin
3 由瀏覽器判斷響應頭
中是否包含Origin
值
4 如果包含瀏覽器會處理響應,返回響應數據翘县;如果不包含瀏覽器直接駁回最域。
Tip
1 支持所有類型的 HTTP 請求。
2 兼容性較差锈麸。
$('.change').addEventListener('click', function(){
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://b.jrg.com:8080/getNews', true);
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
done( JSON.parse(xhr.responseText) )
}
}
})
前端
-------------------------------------------------------------
后端
res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080");
res.send(data); -
降域
解析 主域相同的時候镀脂,把兩個子域設置成相同的父域
過程 document.domain + iframe
document.querySelector('.a input').addEventListener('input',function(){
window.frames[0].document.querySelector('input').value = this.value;
})
document.domain = "jrg.com"
A子域
-------------------------------------------------------------
B子域
document.querySelector('.b input').addEventListener('input', function(){
window.parent.document.querySelector('input').value = this.value;
})
document.domain = 'jrg.com'; -
window.postMessage()
解析 HTML5 的一個新特性,用來向其他所有的window對象發(fā)送消息忘伞。
原理 不同的框架之間可以獲取window對象薄翅。
Tip
必須等所有的腳本執(zhí)行完才發(fā)送MessageEvent,如果在函數執(zhí)行的過程中調用氓奈,就會讓后面的函數超時無法執(zhí)行翘魄。
$('.a input').addEventListener('input', function(){
window.frames[0].postMessage(this.value,'');
})
window.addEventListener('message',function(e) {
$('.main input').value = e.data
});
A子域
-------------------------------------------------------------
B子域
$('.b input').addEventListener('input', function(){
window.parent.postMessage(this.value, '');
})
window.addEventListener('message',function(e) {
$('#input').value = e.data
});
應用
Tip
如何建立兩個不同域的網頁用來測試?(寫給負基礎同學如我)
1 安裝自帶npm的node what?
1.1 下載 這個就行
1.2 安裝一路next
1.3 配置環(huán)境變量 how
1.4 打開 右鍵+shift => 此處打開命令行窗口
ok
1.5 測試 node -v/返回版本號 => nmp -v/返回版本號
ok
2 安裝mock-server what?
npm install -g server-mock
3 修改hosts how
127. 0. 0.1 a.xxx.com
4 打開本地服務器
4.1 測試文件夾下舀奶,調出node窗口
4.2 mock start
5 打開瀏覽器
5.1 a.xxx.com:8080/test1.html
在a域打開測試文件夾下test1
5.2 b.xxx.com:8080/test2.html
在b域打開測試文件夾下test2