前兩天調接口的時候,出現了一個從來沒遇到過的問題。從報錯來看,像是跨域:
Access to XMLHttpRequest at '...' from origin '...' 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.
但是一般來說跨域的報錯並不是這樣,一般是類似於缺少Access-Control-Allow-Origin
header的報錯。
因為我用的是Vue,就先在vue.config.js
的devServer options里配置了proxy,但是沒什么效果;后來配置了nginx進行轉發,仍然是這個報錯,甚至一度讓我懷疑我的nginx配置……當然事實上是沒錯的。而且,我問過后端之后,聽說已經配置了cors,按理說不應該報錯,這就讓我感覺更神秘了。
回去查了一遍代碼,發現我在axios里設置了withCredentials: true
。看到網上有人這么說:
withCredentials的情況下,后端要設置Access-Control-Allow-Origin為你的源地址,例如http://localhost:8080,不能是*,而且還要設置header(‘Access-Control-Allow-Credentials: true’);
說白了就是后端沒允許cookie過去……
另外,Access-Control-Allow-Origin
設置為*時cookie不會出現在http的請求頭里,所以報錯里說Access-Control-Allow-Origin
不能是*也是有道理的。
此外還有一個問題,OPTIONS請求無法通過。我們知道,OPTIONS請求是因為前端發送了“非簡單請求”,比如Content-Type: 'application/json'
,如果后端失誤(或者根本不知道有OPTIONS這種請求),就有可能把OPTIONS擋住,導致無法通過。在不修改后端的情況下,也是有辦法解決這個問題的,就是調整Content-Type: 'application/x-www-form-urlencoded'
,同時將傳輸的JSON進行一次序列化(可以用querystring進行轉換),這樣也能解決問題。