前两天调接口的时候,出现了一个从来没遇到过的问题。从报错来看,像是跨域:
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进行转换),这样也能解决问题。