JS能夠讀取/修改網頁的值。javascript
一個瀏覽器中,打開一個銀行網站和一個惡意網站,若是惡意網站可以對銀行網站進行修改,那麼就會很危險。css
你打開了惡意網站和另外一個網站,若是沒有同源限制,該惡意網站就能夠構造AJAX請求頻繁在另外一個網站發廣告帖。html
同源策略就是爲了解決這類問題而出現的。java
同源策略限制一個加載於A origin的document或者script可以如何和來自於另一個origin的resource交互。同源策略是隔離潛在惡意網頁的安全機制。ajax
瀏覽器的同源策略,限制了來自不一樣源的"document"或腳本,對當前"document"讀取或設置某些屬性。 在瀏覽器中,<script>、<img>、<iframe>、<link>等標籤均可以加載跨域資源,同源策略只對網頁的HTML文檔作了限制,對加載的其餘靜態資源如javascript、css、圖片等仍然認爲屬於同源。chrome
兩個網頁只有具備相同的protocol,port以及host才被認爲是具備相同的origin的。跨域
好比http://xxx.yyy.com:8000/zzz/page.html和http://xxx.yyy.com:8000/kkk/index.html具備相同的originpromise
about:blank
, javascript:
and data:
URLs則從加載那個URL的文件中繼承origin.瀏覽器
同源策略控制了異源之間的互操做,好比,當你使用XMLHttpRequest或者一個<img>元素時就存在這個問題。這些互操做(interactions)典型地放在三個category中:安全
# Apache config <FilesMatch ".(eot|ttf|otf|woff)"> Header set Access-Control-Allow-Origin "*" </FilesMatch>
X-Frame-Options
頭來防止你本身的網頁被別人frame過去!
var invocation = new XMLHttpRequest(); var url = 'http://bar.other/resources/public-data/'; function callOtherDomain() { if(invocation) { invocation.open('GET', url, true); invocation.onreadystatechange = handler; invocation.send(); } }
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
Origin: http://foo.example
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
如何阻止跨域(源)訪問呢?
Cross-orgin script API access
Javascript API,好比iframe.contentWindow, window.parent, window.open,window.opener容許documents來直接引用彼此。當兩個document不一樣源時,這些reference則僅對Window和Location對象開放至關有限的訪問權限,下面將分別列出。
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
<script> <img> <iframe>中的src,href均可以任意連接網絡資源,至關於對所要求的源進行了一次請求。
來自about:blank,JavaScript:和data:URLs中的內容,繼承了將其載入的文檔所指定的源,由於它們的URL自己未指定任何關於自身源的信息。
AJAX跨域的問題
Ajax (XMLHttpRequest)請求應該受到同源策略的限制,可是咱們來看實際狀況:
Ajax經過XMLHttpRequest可以與遠程的服務器進行信息交互,另外XMLHttpRequest是一個純粹的Javascript對象,這樣的交互過程,是在後臺進行的,用戶不易察覺。
所以,XMLHTTP實際上已經突破了原有的Javascript的安全限制。
舉個例子:
假設某網站引用了其它站點的javascript,這個站點被compromise並在javascript中加入獲取用戶輸入並經過ajax提交給其餘站點,這樣就能夠源源不斷收集信息。
或者某網站由於存在漏洞致使XSS注入了javascript腳本,這個腳本就能夠經過ajax獲取用戶信息並經過ajax提交給其餘站點,這樣就能夠源源不斷收集信息。
若是咱們又想利用XMLHTTP的無刷新異步交互能力,又不肯意公然突破Javascript的安全策略,能夠選擇的方案就是給XMLHTTP加上嚴格的同源限制。
這樣的安全策略,很相似於Applet的安全策略。IFrame的限制還僅僅是不能訪問跨域HTMLDOM中的數據,而XMLHTTP則根本上限制了跨域請求的提交。(實際上下面提到了CORS已經放寬了限制)
隨着Ajax技術和網絡服務的發展,對跨域的要求也愈來愈強烈。下面介紹Ajax的跨域技術。
2.1 JSONP
請參考: http://www.jb51.net/article/75484.htm
JSONP技術實際和Ajax沒有關係。咱們知道<script>標籤能夠加載跨域的javascript腳本,而且被加載的腳本和當前文檔屬於同一個域。所以在文檔中能夠調用/訪問腳本中的數據和函數。若是javascript腳本中的數據是動態生成的,那麼只要在文檔中動態建立<script>標籤就能夠實現和服務端的數據交互。
JSONP就是利用<script>標籤的跨域能力實現跨域數據的訪問,請求動態生成的JavaScript腳本同時帶一個callback函數名做爲參數。其中callback函數本地文檔的JavaScript函數,服務器端動態生成的腳本會產生數據,並在代碼中以產生的數據爲參數調用callback函數。當這段腳本加載到本地文檔時,callback函數就被調用。