背景:遷移項目上傳圖片到阿里云的oss存儲報跨域錯誤
報錯信息一:Access to XMLHttpRequest at 'xxxxx' from origin 'xxxxxxxxx' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
錯誤原因:
瀏覽器安全問題,本地路徑和目標路徑不是同一個域名下引起的跨域問題
解決方法也很簡單,因為瀏覽器解析域名的時候會先看下hosts有沒有,如果本地hosts存在該域名就會使用改域名
1.設(shè)置本地hosts
127.0.0.1 test.com
2.設(shè)置代理
可以在webpack的proxy設(shè)置也可以用nginx設(shè)置,個人喜歡nginx更符合線上環(huán)境
server {
listen 80;
server_name test.com;
location /{
proxy_pass http://127.0.0.1:xxx;// 你的項目端口
}
}
設(shè)置完這兩步一般都可以解決大部分的代理問題
報錯信息二:Access to XMLHttpRequest at 'xxxxxx' from origin 'xxxx' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
網(wǎng)上找了各種花里胡哨答案,,,沒用,后面發(fā)現(xiàn)只需要設(shè)置一個屬性就解決了
withCredentials: false,
完美解決圖片上傳跨域問題
axios({
url: "xxx",
method: "POST",
data,
withCredentials: false,
}).then(res => {
});
發(fā)現(xiàn)是同事在axios請求中添加了這個代碼,醉了。。。。。。。
axios.defaults.withCredentials = true;//
后面去MDN查了下這個屬性:
XMLHttpRequest.withCredentials 屬性是一個Boolean類型,它指示了是否該使用類似cookies,authorization headers(頭部授權(quán))或者TLS客戶端證書這一類資格證書來創(chuàng)建一個跨站點訪問控制(cross-site Access-Control)請求。在同一個站點下使用withCredentials屬性是無效的。
此外,這個指示也會被用做響應(yīng)中cookies 被忽視的標示。默認值是false。
如果在發(fā)送來自其他域的XMLHttpRequest請求之前,未設(shè)置withCredentials 為true,那么就不能為它自己的域設(shè)置cookie值。而通過設(shè)置withCredentials 為true獲得的第三方cookies,將會依舊享受同源策略,因此不能被通過document.cookie或者從頭部相應(yīng)請求的腳本等訪問
瀏覽器兼容性
[1]IE8 和IE9通過使用 XDomainRequest 支持跨域請求
[2] 從 Gecko 11.0 (Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8)開始, Gecko 不允許在同步請求下使用withCredentials 屬性.嘗試這么做將會導(dǎo)致瀏覽器拋出 NS_ERROR_DOM_INVALID_ACCESS_ERR exception的錯誤.
總結(jié):
withCredentials默認值為false,在獲取同域資源時設(shè)置 withCredentials 沒有影響。
true:在跨域請求時,會攜帶用戶憑證
false:在跨域請求時,不會攜帶用戶憑證;
返回的 response 里也會忽略 cookie