前端開發(fā)的童鞋,應(yīng)該都有聽過跨域請求,但這其中的細節(jié)可能還不清楚,比如:
<pre>
- 什么是跨域請求?
- 為什么會存在跨域請求?
- 跨域請求是怎么工作的?
- 如何解決跨域請求?
</pre>
1. 什么是跨域請求
跨域請求 - 訪問其他域名的資源,隨著業(yè)務(wù)的復(fù)雜化及前后端的分離,我們需要經(jīng)常訪問其他域名的資源,因此這里就涉及到跨域訪問,下圖給出了跨域訪問的例子

2. 為什么會存在跨域請求
可能有童鞋就說了,何必這么麻煩,直接允許訪問不就行了,也許前期就是這樣,于是就出現(xiàn)了CSRF(跨站請求偽造),可以看下圖:

因此網(wǎng)站A就必須添加訪問限制,即決策是否允許網(wǎng)站B訪問
3. 跨域請求是怎么工作的
跨域請求針對不同的請求會采用不用的策略,這里羅列如下:
3.1 簡單模式(Simple requests)
請求方法:
GET
HEAD
POST
請求頭:
Accept
Accept-Language
Content-Language
Content-Type
Content-Type:
application/x-www-form-urlencoded
multipart/form-data
text/plain
滿足以上特征的請求就是Simple request,采用如下工作模式:
- 瀏覽器從網(wǎng)站B獲取html資源
- 瀏覽器發(fā)送請求到網(wǎng)站A,并攜帶網(wǎng)站B的Origin,如Server-b.com
- 網(wǎng)站A檢測自身的Access-Control-Allow-Origin是否包含Origin,如果包含返回正確數(shù)據(jù),否則返回空

PS: Access-Control-Allow-Origin: * 表示允許所有網(wǎng)站方法
3.2 預(yù)檢模式(Preflighted requests)
除了簡單請求外,其他請求訪問前需要先發(fā)一條預(yù)檢請求,比如采用OPTIONS,采用如下工作模式:
- 瀏覽器從網(wǎng)站B獲取html資源
- 瀏覽器發(fā)送OPTIONS請求,并攜帶如下信息
- Origin - 網(wǎng)站B域名
- Access-Control-Request-Method - 待請求方法,如POST
- Access-Control-Request-Headers - 待請求頭信息
- 網(wǎng)站A檢測自身的Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers是否包含客戶端發(fā)送的值
- 如果包含,則返回200,瀏覽器發(fā)送真正的請求(也需要攜帶CROS信息),服務(wù)器返回正確數(shù)據(jù)
- 如果不包含,則返回錯誤,并返回Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers

4. 常見錯誤
- 4.1 Access-Control-Allow-Origin不匹配
一般會報如下錯誤:已攔截跨源請求:同源策略禁止讀取位于 http://127.0.0.1:19110/uptoken 的遠程資源。(原因:CORS 頭 'Access-Control-Allow-Origin' 不匹配 '1')
解決方法:檢測服務(wù)端配置的Access-Control-Allow-Origin,應(yīng)該包含前端所在服務(wù)的域名
- 4.2 Access-Control-Allow-Headers不匹配
一般會報如下錯誤:已攔截跨源請求:同源策略禁止讀取位于 http://127.0.0.1:19110/uptoken 的遠程資源。(原因:來自 CORS 預(yù)檢通道的 CORS 頭 'Access-Control-Allow-Headers' 的令牌 'if-modified-since' 無效)
解決方法:檢測服務(wù)端配置的Access-Control-Allow-Headers,應(yīng)該包含前端發(fā)送的Access-Control-Request-Headers(可以抓包看前端發(fā)送的數(shù)據(jù))
更多
- 跨域是瀏覽器行為
- HTTP access control (CORS)
- 淺談CSRF攻擊方式