前言: 當(dāng)一個資源,向與之所在服務(wù)器不同的域或端口請求另一個資源時,這個HTTP請求,我們認(rèn)為是跨域的請求。出于安全考慮,瀏覽器會限制腳本發(fā)起的跨域HTTP請求。
那天后端讓我把token放到http請求頭字段里,說是為了和RN端統(tǒng)一,在此之前我都是放在請求體或者URL里的。于是我改請求封裝部分的代碼,在header里加了個
headers:{
'access_token':config.token
}
保存+reload。。一排報錯。。
Failed to load http://116.62.235.215:10081/api/order: Request header field access_token is not allowed by Access-Control-Allow-Headers in preflight response.
之前已經(jīng)為跨域做了設(shè)置了,后端也給響應(yīng)加了Access-Control-Allow-Origin: *,怎么還會遇到跨域的問題呢。
緊接著我發(fā)現(xiàn)這些請求都是 OPTIONS ??噢,不是說簡單請求(這個請求是 content-type為 application/x-www-form-urlencoded的post請求)不會觸發(fā) CORS 預(yù)檢請求嗎?
雖然抱著一堆疑問,我還是給后端大哥說,既然報錯的是Access-Control-Allow-Headers,你在響應(yīng)頭加一個 Access-Control-Allow-Headers :"access_token",我們再試試。
于是,果然好了,但是請求數(shù)直接翻了一番,所有的請求都會先發(fā)一個options,再是請求本身。。。那可不行啊,一下把所有的請求時間都翻倍了,最后我們?nèi)匀皇褂玫呐f有的方案。
但是問題并沒有解決,首先
1.為什么會發(fā)一個 options 請求呢?
2.可否緩存這個 options 請求, 之后的請求就不用預(yù)檢了呢?
3.加個headers還需要先向服務(wù)器報備呢?
帶著這些問題 我再看了看 HTTP訪問控制(CORS)
@Q1:為什么會發(fā)一個 options 請求呢?
簡單請求 除了滿足下圖外,還需滿足另一個條件,因為使用的比較少,我直接忽略了。
需要滿足上面兩圖的條件才歸類為簡單請求,我對請求的headers添加了一個自定義的頭,自然不符合,所以出現(xiàn)了預(yù)檢請求。
如果預(yù)檢請求響應(yīng)頭返回的字段不符合真實(shí)請求的信息,便不會發(fā)起真實(shí)請求。
其實(shí)這個問題還能再問。。為什么是 options 呢?
OPTIONS用于獲取目的資源所支持的通信選項。(大概是協(xié)議定的吧。。)
@Q2:可否緩存這個 options 請求, 之后的請求就不用預(yù)檢了呢?
對于同一個請求是存在緩存概念的,響應(yīng)頭的Access-Control-Max-Age的值決定了預(yù)檢請求的緩存時間。
@Q3: 加個headers還需要先向服務(wù)器報備呢?
看簡單請求的條件,然后可以得出 要加的header是否標(biāo)準(zhǔn)(這里的標(biāo)準(zhǔn)似乎不同瀏覽器有不同..實(shí)際需再考量。)
說實(shí)話我還想知道為什么要限制。。
什么是CSRF
假如銀行用于轉(zhuǎn)賬操作的URL :http:www.bank.com/transfer?account=name&amount=number
那么以一個惡意攻擊者在另一個網(wǎng)站防止如下代碼: http:www.bank.com/transfer?account=anshi&amount=3000
如果有anshi在登錄銀行不久,且登錄信息并未過期,此時她再訪問該惡意網(wǎng)站,那么他就會損失3000元。
也就是說,這種方式能做到 欺騙用戶瀏覽器,讓其以用戶的身份執(zhí)行操作。
問題:
1.在另一個網(wǎng)站為什么能帶著其他網(wǎng)站的身份信息?
HTTP的一個特性是..基于 cookie 和 http 認(rèn)證信息發(fā)送身份憑證,也就是說不管發(fā)起請求的地址,而是看送往請求的地址,送到A站,就會攜帶A站的 身份信息。
一般來說,跨域請求,瀏覽器不會發(fā)送身份憑證...那上述例子是因為采用標(biāo)簽跨域的所以能攜帶用戶信息?
2.其他的預(yù)防方式?
referer 或者 在請求參數(shù)中攜帶 token ;
那JSONP所謂的解決方案?
HTML自帶標(biāo)簽的本身不受跨域的限制,自然就滿足了某些需要跨域的需求。但是如果服務(wù)器對該請求的來源有限制,估計也是訪問不了的。
參考資料:
讓我們來談?wù)?CSRF
HTTP訪問控制(CORS)