什么是跨域問題?如何解決?

1. 概述
幾個(gè)疑問:
什么是跨域?
如何判斷是否產(chǎn)生「跨域」?
跨域,帶來的問題?
跨域問題,解決思路?
2. 跨域:是什么
跨域的問題根源:瀏覽器的「同源策略」。
2.1. 同源策略
同源策略(Same-Origin Policy):1995 年,Netscape 公司,將「同源策略」引入瀏覽器,此后,所有瀏覽器都遵循「同源策略」。
同源策略:
A 網(wǎng)頁設(shè)置的 Cookie,B 網(wǎng)頁不能訪問,除非「A B 同源」。
即:
非同源網(wǎng)站之間, Cookie 隔離。
同源:是指「3 個(gè)相同」
協(xié)議
域名
端口
同源策略的意義:瀏覽器安全的基石,保證用戶信息安全,防止惡意網(wǎng)站竊取數(shù)據(jù)。
Cookie 是存儲在瀏覽器端的文本信息,通常存儲一些個(gè)人隱私信息,大部分網(wǎng)站通過 Cookie 內(nèi)信息識別用戶的登陸狀態(tài),如果 Cookie 被惡意竊取,則產(chǎn)生巨大安全隱患。
思考:
同源的網(wǎng)站,會共享 Cookie,還會共享其他信息么?
隨著互聯(lián)網(wǎng)的發(fā)展,更加嚴(yán)格的「同源策略」:如果 A網(wǎng)站和 B網(wǎng)站,不同源,則
Cookie、LocalStorage 和 IndexDB 無法讀取
DOM 無法獲得
AJAX 請求不能發(fā)送
「同源策略」絕大部分情況下,都很必要,但也限制了業(yè)務(wù)的靈活應(yīng)用,一些特殊場景下,期望繞過「同源策略」。
2.2. 跨域
核心幾點(diǎn):
跨域:
發(fā)生在瀏覽器
跨域的根源:
瀏覽器為了安全所遵循的「同源策略」
同一個(gè)域:
3 個(gè)相同
3. 跨域:帶來的問題
跨域時(shí),2 個(gè)請求無法共享 Cookie 等數(shù)據(jù),也無法嵌套發(fā)送 Ajax 請求。
解決辦法:
請求無法共享 Cookie 數(shù)據(jù):
網(wǎng)頁設(shè)置 document.domain 參數(shù),實(shí)現(xiàn)一級域名共享 Cookie
無法嵌套發(fā)送 Ajax 請求:
需要特殊處理。
(見下文)
跨域:解決方案
3.1. Cookie
Cookie 是服務(wù)器寫入瀏覽器的一小段信息,只有同源的網(wǎng)頁才能共享。但是,兩個(gè)網(wǎng)頁一級域名相同,只是二級域名不同,瀏覽器允許通過設(shè)置document.domain共享 Cookie。
舉例來說,A網(wǎng)頁是http://w1.example.com/a.html,B網(wǎng)頁是http://w2.example.com/b.html,那么只要設(shè)置相同的document.domain,兩個(gè)網(wǎng)頁就可以共享Cookie。
document.domain = 'example.com';現(xiàn)在,A網(wǎng)頁通過腳本設(shè)置一個(gè) Cookie。
document.cookie = "test1=hello";B網(wǎng)頁就可以讀到這個(gè) Cookie。
var?allCookie = document.cookie;注意,這種方法只適用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 無法通過這種方法,規(guī)避同源政策,而要使用PostMessage API。另外,服務(wù)器也可以在設(shè)置Cookie的時(shí)候,指定Cookie的所屬域名為一級域名,比如.example.com。
Set-Cookie: key=value; domain=.example.com; path=/這樣的話,二級域名和三級域名不用做任何設(shè)置,都可以讀取這個(gè)Cookie。
3.2. Ajax
同源政策規(guī)定,AJAX請求只能發(fā)給同源的網(wǎng)址,否則就報(bào)錯(cuò)。
除了架設(shè)服務(wù)器代理(瀏覽器請求同源服務(wù)器,再由后者請求外部服務(wù)),有三種方法規(guī)避這個(gè)限制。
JSONP
WebSocket
CORS
3.2.1. JSONP
本質(zhì):
網(wǎng)頁內(nèi)部,通過
服務(wù)端受到請求后,需要將 data 放入指定名字「回調(diào)函數(shù)」中傳回,避免使用 JSON.parse 步驟。
特點(diǎn):
需要服務(wù)器配套改造。
3.2.2. CORS
CORS是跨源資源分享(Cross-Origin Resource Sharing)的縮寫。它是W3C標(biāo)準(zhǔn),是跨源AJAX請求的根本解決方法。相比JSONP只能發(fā)GET請求,CORS允許任何類型的請求。
關(guān)鍵點(diǎn):
CORS需要瀏覽器和服務(wù)器同時(shí)支持。
目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10。
整個(gè)CORS通信過程,都是瀏覽器自動(dòng)完成,不需要用戶參與。
對于開發(fā)者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。
瀏覽器一旦發(fā)現(xiàn)AJAX請求跨源,就會自動(dòng)添加一些附加的頭信息,有時(shí)還會多出一次附加的請求,但用戶不會有感覺。
因此,實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了CORS接口,就可以跨源通信。
瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。
只要同時(shí)滿足以下兩大條件,就屬于簡單請求。
(1) 請求方法是以下三種方法之一:
HEAD
GET
POST
(2)HTTP的頭信息不超出以下幾種字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:
只限于三個(gè)值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同時(shí)滿足上面兩個(gè)條件,就屬于非簡單請求。瀏覽器對這兩種請求的處理,是不一樣的。?
原文鏈接:ningg.top/computer-basic-theory-cors/
