xhr.withCredentials發送跨域請求憑證
一、前言
今天遇到一個坑,瀏覽器請求數據的時候gg了。瀏覽器報錯如下圖:
因為請求頭部設置了credentis mode is ‘include‘, 從上面可以看出是Access-Control-Allow-Credentials這個響應必須設置為true。
二、思考
第一反應前端沒有設置過這個值啊?應該走默認才對吧?測試環境OK啊!
---------------------------------真是一萬只野馬狂奔而過啊-------------------------------------
由於之前沒有遇到過這個問題,對這個也沒怎麽關註,所以排錯慢了點。
後面查了一下資料,然後回歸一下代碼,oh my god! 其他前端寶寶在請求中設置了這個:(因為是合作開發,我也沒有註意這個,此處沒有甩鍋的ys)
config.withCredentials = true
那麽前端設置上面這個有啥用?那為什麽加了就報錯呢?後臺難道沒有配合設置對應相應頭部嗎?
【後續想起】估計是後臺小哥哥說過:“前端最好給後臺傳cookie和token” 這句話吧,導致前端小哥哥加上了這個設置,不過後面後臺並沒有設置cookie。所以沒必要加啊,這就是信息不對稱導致結果吧。
三、原理及處理方法
1、標準的跨域請求是不會發送cookie等用戶認證憑據的,XMLHttpRequest 2的一個重要改進就是提供了對授信請求訪問的支持。也就是說,如果發生跨域請求,又想攜帶cookie到服務器,前端請求和後端響應都必須設置:
2、前端請求:
var xhr = new XMLHttpRequest(); xhr.open(‘GET‘, ‘http://www.xxx.com/api‘); xhr.withCredentials = true; xhr.onload = onLoadHandler; xhr.send();
或者在axios請求配置中設置:
3、服務端響應頭:
Access-Control-Allow-Credentials: true
如果服務端不設置該響應頭,瀏覽器會報錯,當然響應會被忽略不可用;
同時,服務端需指定一個域名(Access-Control-Allow-Origin:www.xxx.com),而不能使用泛型(Access-Control-Allow-Origin: *)不然即使設置了該頭部,cookie開始不能轉到服務器。
四、總結
1、本次錯誤是因為前端配置了Credentials:true,但是瀏覽器沒有設置Access-Control-Allow-Credentials: true,且響應是Access-Control-Allow-Origin:*;
2、如果在跨域中希望瀏覽器能攜帶cookie到服務器,前後端都應該設置Credentials的值為true, 且Access-Control-Allow-Origin就不能設為星號,必須指定明確的,與請求網頁一致的域名。,不然cookie還是不能攜帶過去;
3、Cookie依然遵循同源政策,只有用服務器域名設置的Cookie才會上傳,其他域名的Cookie並不會上傳,且(跨源)原網頁代碼中的document.cookie也無法讀取服務器域名下的Cookie;
4、如果服務器不要瀏覽器發送cookie,前後端都不設置這個字段就好了。
xhr.withCredentials發送跨域請求憑證