跨域是指從一個域名的網頁去訪問另外一個域名的網頁。一個完整URL地址一般由 協議+主機+端口+路徑[+hash或search] 組成,其中hash和search是可選項、協議未列出則默認爲http、port未列出則默認爲80值。所以嚴格來講,兩個網頁地址的協議(http/https)、主機、端口三者任何一個不一樣就能夠認爲是跨域訪問,即便兩個地址是不一樣子域名也是跨域,如app.baidu.com與baidu.com。javascript
瀏覽器出於安全考慮會限制跨域訪問(即同源策略)。在該限制下,除非兩個網頁是來自於同一‘源頭’, 不然不容許一個網頁的JavaScript訪問另一個網頁的內容,像Cookie,DOM,LocalStorage均禁止訪問;但對具備src屬性的標籤(如script、img、iframe等)不作跨域限制。html
瀏覽器出於安全考慮會限制跨域訪問,若不加限制則在一個站點上訪問後本地存儲的cookie等信息在訪問第二個站點時就可能泄露了。(從這可見,跨域限制只是在經過瀏覽器訪問時才存在,所以經過HTTP客戶端等訪問顯然沒有跨域限制問題)前端
沒有同源限制時的危害示例:java
在瀏覽器上先登陸股票網站www.stock.com,獲得了cookie,之後再訪問stock時瀏覽器會自動帶上cookie;接着訪問惡意網站www.beautify.com,假定該網站頁面中包含一個惡意js腳本,其行爲是去訪問stock並把獲得的信息發到beautify網站,因爲訪問stock時瀏覽器會自動帶上cookie故惡意腳本能夠成功竊取到數據。示意圖以下:ajax
上述過程就是跨站請求僞造(Cross-site request forgery,CSRF)的一種例子,所幸在有瀏覽器同源策略的限制下上述狀況不會發生。編程
所以,瀏覽器同源策略的做用是防止跨站請求僞造。json
瀏覽器的同源限制是種傷敵一千自損八百的作法,如對於一個大系統來講有不少域名是正常的,同源限制使得同一系統內的不一樣域名下的服務沒法互相訪問。後端
要突破瀏覽器跨域訪問的限制,本質上有三種方法:跨域
注:瀏覽器
JSONP、CORS須要目標站點的配合(JSONP須要服務端代碼調用回調函數、CORS須要服務端配置容許的origin的白名單),不然沒法實現,第一種則不須要;
AJAX已封裝支持了JSONP功能,但此時其和傳統意義上的AJAX請求是不同的,本質上是不一樣東西:ajax的核心是經過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態添加<script>標籤來調用服務器提供的js腳本。更多參考:jsonp原理
CORS與JSONP的使用目的相同,可是比JSONP更強大。JSONP只支持GET請求,CORS支持全部類型的HTTP請求。JSONP的優點在於支持老式瀏覽器,以及能夠向不支持CORS的網站請求數據。
思考:上一節中所述危害是以沒有同源限制爲前提的,現實是瀏覽器都作了嚴格的同源限制,故該狀況不會發生。然而在有同源限制下,咱們仍可利用法2實現一個盜取用戶信息的惡意腳本:
一、腳本乾的事爲讀取當前所在用戶站點的cookie等信息,併發送到腳本製做者的站點;
二、發送涉及到跨域,因爲是「本身人」,能夠選擇jsonp解決跨域;
三、弄個惡意連接誘導用戶點擊,從而將惡意腳本加載到用戶站點,因爲瀏覽器加載完script後就好執行,故done。
上述過程其實就是跨站腳本攻擊(Cross-Site Scripting,XSS)的一種例子,經過XSS獲取到認證信息後就自熱而然地能夠用認證信息進行CSRF了。
瀏覽器的同源策略用來確保在瀏覽器內對後端發起訪問的前端是可信賴的前端。除了依靠瀏覽器源限制外,後端服務還能夠根據所收到請求的origin字段來限制白名單(origin字段由瀏覽器自動加入HTTP header,用戶沒法經過編程方式如javascript修改;固然,經過中間人攻擊仍是能夠修改的,此時可用HTTPS或wss防範)。
目前,對於新興的WebSocket協議(2008年誕生,2011年成爲國際標準,目前全部瀏覽器都已支持),瀏覽器未作同源限制。所以應用要注意防範CSRF攻擊,可藉助token或上述的origin等方式防範。