什么是跨域?
跨域問題是由于瀏覽器為了防止CSRF攻擊,避免惡意攻擊而帶來的風(fēng)險(xiǎn)而采取的同源策略限制。當(dāng)一個(gè)頁面中使用XMLHTTPRequest對(duì)象發(fā)送HTTP請(qǐng)求時(shí)(XHR請(qǐng)求),必須保證當(dāng)前頁面和請(qǐng)求的對(duì)象是同源的,即協(xié)議、域名和端口號(hào)要完全一致,否則瀏覽器就會(huì)阻止此跨域請(qǐng)求返回的數(shù)據(jù)
同源策略
| 域名A | 域名B | 是否允許通信 |
|---|---|---|
| http://www.a.com | https://www.a.com | 否 |
| http://www.a.com | http://www.b.com | 否 |
| http://www.a.com:80 | http://www.a.com:8080 | 否 |
什么是JSONP?
JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式,而JSONP(JSON with Padding)則是JSON 的一種“使用模式”,通過這種模式可以實(shí)現(xiàn)數(shù)據(jù)的跨域獲取。
JSONP跨域的原理
在同源策略下,在某個(gè)服務(wù)器下的頁面是無法獲取到該服務(wù)器以外的數(shù)據(jù)的,但img、iframe、script等標(biāo)簽是個(gè)例外,這些標(biāo)簽可以通過src屬性請(qǐng)求到其他服務(wù)器上的數(shù)據(jù)。利用script標(biāo)簽的開放策略,我們可以實(shí)現(xiàn)跨域請(qǐng)求數(shù)據(jù),當(dāng)然,也需要服務(wù)端的配合。
當(dāng)我們正常地請(qǐng)求一個(gè)JSON數(shù)據(jù)的時(shí)候,服務(wù)端返回的是一串JSON類型的數(shù)據(jù),而我們使用JSONP模式來請(qǐng)求數(shù)據(jù)的時(shí)候,服務(wù)端返回的是一段可執(zhí)行的JavaScript代碼。
例如
<script type="text/javascript" src="http://www.a.com?callback=jsonpCallback" />
// 回調(diào)函數(shù)function jsonpCallback(){ }
</script>
整個(gè)過程為:
- script標(biāo)簽設(shè)置src屬性為請(qǐng)求的地址,并判斷回調(diào)函數(shù)作為參數(shù)
- 服務(wù)端構(gòu)建JS腳本,傳遞返回給客戶端的數(shù)據(jù)
- 客戶端在回調(diào)函數(shù)中解析服務(wù)器生成的數(shù)據(jù)
這樣就可以實(shí)現(xiàn)瀏覽器頁面的跨域請(qǐng)求,但使用jsonp處理跨域有個(gè)很明顯額缺點(diǎn),就是只支持GET,不支持POST請(qǐng)求,就引出了目前使用較廣的一種處理跨域的方法:CORS跨域資源共享機(jī)制
什么是CORS?
跨域資源共享(CORS) 是一種機(jī)制,它允許服務(wù)器使用新增的 HTTP 頭部信息來告訴瀏覽器準(zhǔn)許訪問來自不同源服務(wù)器上指定的資源。
某接口返回的response header如下

Access-Control-Allow-Origin
這個(gè)頭部信息由服務(wù)器返回,用來明確指定那些客戶端的域名允許訪問這個(gè)資源。它的值可以是:
- —— 允許任意域名
https://wqs.jd.com —— 一個(gè)完整的域名名字
如果接口請(qǐng)求是需要驗(yàn)證用戶身份(request header中包含cookie),那返回的這個(gè)值不能為 * 號(hào),必須為完整的域名
Access-Control-Allow-Headers
提供一個(gè)逗號(hào)分隔的列表表示服務(wù)器支持的請(qǐng)求數(shù)據(jù)類型。假如你使用自定義頭部(比如:x-authentication-token 服務(wù)器需要在返回OPTIONS請(qǐng)求時(shí),要把這個(gè)值放到這個(gè)頭部里,否則請(qǐng)求會(huì)被阻止)。
Access-Control-Allow-Methods
一個(gè)逗號(hào)分隔的列表,表明服務(wù)器支持的請(qǐng)求類型(比如:GET,POST,OPTIONS)
Access-Control-Allow-Credentials
這個(gè)頭部信息只會(huì)在服務(wù)器支持通過cookies傳遞驗(yàn)證信息時(shí)才會(huì)返回。它的值只有一個(gè)就是 true。只有這個(gè)值被返回時(shí),才允許瀏覽器讀取response的內(nèi)容。
還有其他的HTTP頭部字段以及使用PUT、DELETE、OPTiON方法請(qǐng)求時(shí)的預(yù)檢查機(jī)制,詳細(xì)可了解可查詢官方文檔:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS