has been blocked by CORS policy: Request header field authentication is not allo

3,631 阅读2分钟

记录遇到的bug,所以写的可能不是很好一下午的一个总结吧。

我也是看了他的文章才解决的,可以优先看他的他比我写的好一百倍

前端在请求服务器的时候跨域了,可是我明明已经做了跨域处理怎么还会报错了。

has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: 
It does not have HTTP ok status.

截屏2022-11-26 17.24.48.png 这个时候我发现我的请求他里面带了自定义的请求头,“Authentication”用来认证用户是否有登录。当我把它取消的时候发现可以正常请求了。这就奇了怪了。

搜索了一下才知道跨域请求还分简单请求和复杂请求,

1): 请求方式只能是:head,get,post
2): 请求头允许的字段:Accept,Accept-Language,Content-Language,Last-Event-ID
Content-Type:application/x-www-form-urlencoded、multipart/form-data、text/plain 三选一

当我取消了自定的请求头Authentication后,变成了简单请求因为之前做了跨域便可以正常请求了。 那怎么处理复杂的请求呢?

当我们发起复杂请求的时候浏览器会先发送一个option请求到服务器,进行预检如果不对预检进行处理则没办法进行复杂的跨越请求。

截屏2022-11-26 17.34.53.png

所以这个时候服务器需要对浏览器发起的option请求进行处理;

        if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
            response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
            response.setHeader("Access-Control-Max-Age", "1800");
            response.setHeader("Access-Control-Allow-Headers", "*");
            response.setStatus(HttpStatus.NO_CONTENT.value());
            return false;
        }

OK这下应该可以跑通了吧...

    Access to XMLHttpRequest at 
    'http://localhost:8443/api/getArticleList?pageSize=20&currentPage=0' 
    from origin 'http://localhost:3000' has been blocked by CORS policy: 
    Request header field authentication is not allowed by 
    Access-Control-Allow-Headers in preflight response.

怎么回事啊我的哥我明明又做了处理啊...继续搜索问题 终于让我找到了,原来是当设置了

// 允许携带cookie
response.setHeader("Access-Control-Allow-Credentials", "true");
// 自定义请求头
response.setHeader("Access-Control-Allow-Headers", "*");

response.setHeader("Access-Control-Allow-Credentials", "true");的时候response.setHeader("Access-Control-Allow-Headers不能为*

改成我们想要的

response.setHeader("Access-Control-Allow-Headers", "Authentication");

截屏2022-11-26 17.51.00.png

👌请求成功;我这里报错401是因为没有携带token认证不通过正常逻辑啦。

总结

简单跨域浏览器只对比请求头origin是否和相应头的Access-Control-Allow-Origin匹配,如果匹配则可以正常发起请求。 复杂跨域需要服务器处理浏览器发送option请求,并设置对应的响应头浏览器看到了之后根据响应头的设置,检查是否发起该请求。

我也是遇到了这个问题搞了一下午。