Http同源限制

同源
Cookic
Document.cookic
Http返回html

1.概述
1.1含義
1.2目的
1.3限制範圍
2.Cookie 同源
3.iframe 和多窗口通訊
3.1片斷識別符 # 穿數據 父子窗口
3.2window.postMessage()可不一樣 父子窗口
3.3LocalStorage 同源父子窗口
4.AJAX 服務器和客戶端之間
4.1JSONP 在script標籤加callback 參數就是數據體 Get
4.2WebSocket
4.3CORS
參考連接web

domcument.domainapi

1.概述

1.1含義

A 網頁設置的 Cookie,B 網頁不能打開,除非這兩個網頁「同源」。所謂「同源」指的是「三個相同」。跨域

  • 協議相同
  • 域名相同
  • 端口相同

1.2目的

同源政策的目的,是爲了保證用戶信息的安全,防止惡意的網站竊取數據。瀏覽器

設想這樣一種狀況:A 網站是一家銀行,用戶登陸之後,A 網站在用戶的機器上設置了一個 Cookie,包含了一些隱私信息(好比存款總額)。用戶離開 A 網站之後,又去訪問 B 網站,若是沒有同源限制,B 網站能夠讀取 A 網站的 Cookie,那麼隱私信息就會泄漏。
更可怕的是,Cookie 每每用來保存用戶的登陸狀態,若是用戶沒有退出登陸,其餘網站就能夠冒充用戶,隨心所欲。
由於瀏覽器同時還規定,提交表單不受同源政策的限制。安全

1.3限制範圍

1.沒法讀取非同源cookic.localstorage,indexesDB
.2.沒法讀取dom服務器

  1. 沒法向非同源地址發送 AJAX 請求(能夠發送,但瀏覽器會拒絕接受響應)。

另外,經過 JavaScript 腳本能夠拿到其餘窗口的window對象。若是是非同源的網頁,目前容許一個窗口能夠接觸其餘網頁的window對象的九個屬性和四個方法。websocket

window.closed
window.frames
window.length
window.location
window.opener
window.parent
window.self
window.top
window.window
window.blur()
window.close()
window.focus()
window.postMessage()dom

上面的九個屬性之中,只有window.location是可讀寫的,其餘八個所有都是隻讀。並且,即便是location對象,非同源的狀況下,也只容許調用location.replace方法和寫入location.href屬性socket

2.Cookie 同源

次級域名不一樣的,能夠改相同document.domain來共享cookic

舉例來講,A 網頁的網址是http://w1.example.com/a.html,B 網頁的網址是http://w2.example.com/b.html,那麼只要設置相同的document.domain

注意,A 和 B 兩個網頁都須要設置document.domain屬性,才能達到同源的目的。由於設置document.domain的同時,會把端口重置爲null,所以若是隻設置一個網頁的document.domain,會致使兩個網址的端口不一樣,仍是達不到同源的目的

注意,這種方法只適用於 Cookie 和 iframe 窗口,LocalStorage 和 IndexedDB 沒法經過這種方法,規避同源政策,而要使用下文介紹 PostMessage API

3.iframe 和多窗口通訊

Iframe用於在頁面中嵌入頁面,每一個iframe造成本身的窗口。本身的windom對象。

iframe窗口之中的腳本,能夠得到父窗口和子窗口。
可是,只有在同源的狀況下,父窗口和子窗口才能通訊;若是跨域,就沒法拿到對方的 DOM

document
.getElementById("myIFrame")
.contentWindow
.document
// Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.
上面命令中,父窗口想獲取子窗口的 DOM,由於跨域致使報錯。

反之亦然,子窗口獲取主窗口的 DOM 也會報錯。

window.parent.document.body
// 報錯

對於徹底不一樣源的網站,目前有兩種方法,能夠解決跨域窗口的通訊問題。

片斷識別符(fragment identifier)
跨文檔通訊API(Cross-document messaging)

3.1片斷識別符 # 傳數據

Url#後面的

若是隻是改變片斷標識符,頁面不會從新刷新。

父窗口能夠把信息,寫入子窗口的片斷標識符。

var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;

window.onhashchange = checkMessage;

function checkMessage() {
var message = window.location.hash;
// ...
}
一樣的,子窗口也能夠改變父窗口的片斷標識符。

parent.location.href = target + '#' + hash;

3.2window.postMessage()可不一樣

舉例來講,父窗口aaa.com向子窗口bbb.com發消息,調用postMessage方法就能夠了

// 父窗口打開一個子窗口
var popup = window.open('http://bbb.com', 'title');
// 父窗口向子窗口發消息
popup.postMessage('Hello World!', 'http://bbb.com');
postMessage方法的第一個參數是具體的信息內容,第二個參數是接收消息的窗口的源(origin),即「協議 + 域名 + 端口」。也能夠設爲*,表示不限制域名,向全部窗口發送。

子窗口向父窗口發送消息的寫法相似。

// 子窗口向父窗口發消息
window.opener.postMessage('Nice to see you', 'http://aaa.com');

父窗口和子窗口均可以經過message事件,監聽對方的消息。

// 父窗口和子窗口均可以用下面的代碼,
// 監聽 message 消息
window.addEventListener('message', function (e) {
console.log(e.data);
},false);
message事件的參數是事件對象event,提供如下三個屬性。

event.source:發送消息的窗口
event.origin: 消息發向的網址
event.data: 消息內容

下面的例子是,子窗口經過event.source屬性引用父窗口,而後發送消息。

window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
event.source.postMessage('Nice to see you!', '*');
}

3.3LocalStorage 同源

4.AJAX

除了架設服務器代理(瀏覽器請求同源服務器,再由後者請求外部服務),有三種方法規避這個限制。

4.1.JSONP

第一步,網頁添加一個<script>元素,向服務器請求一個腳本,這不受同源政策限制,能夠跨域請求。

<script src="http://api.foo.com?callback=b...;></script>
注意,請求的腳本網址有一個callback參數(?callback=bar),用來告訴服務器,客戶端的回調函數名稱(bar)。

第二步,服務器收到請求後,拼接一個字符串,將 JSON 數據放在函數名裏面,做爲字符串返回(bar({...}))。

第三步,客戶端會將服務器返回的字符串,做爲代碼解析,由於瀏覽器認爲,這是<script>標籤請求的腳本內容。這時,客戶端只要定義了bar()函數,就能在該函數體內,拿到服務器返回的 JSON 數據。

4.2.WebSocket

通訊協議
使用ws://(非加密)和wss://(加密)做爲協議前綴。該協議不實行同源政策,只要服務器支持,就能夠經過它進行跨源通訊

下面是一個例子,瀏覽器發出的 WebSocket 請求的頭信息(摘自維基百科)。

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
上面代碼中,有一個字段是Origin,表示該請求的請求源(origin),即發自哪一個域名

正是由於有了Origin這個字段,因此 WebSocket 纔沒有實行同源政策。由於服務器能夠根據這個字段,判斷是否許可本次通訊。若是該域名在白名單內,服務器就會作出以下回應。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

4.3.CORS

相比 JSONP 只能發GET請求,CORS 容許任何類型的請求

相關文章
相關標籤/搜索