不知道你在做前端开发的时候有没有遇到一种情况,请求成功的话不会提示跨域,但是请求失败的情况却会提示跨域。我前几天就被这个情况困扰到了,我的nodejs
服务没有使用cors
去处理跨域,而是在nginx
里面处理的,起初就是用下面的配置,当浏览器请求成功的时候一切正常,后来我加了个鉴权功能,没接口访问权限的情况返回了401
的状态码,但是前端的请求代码中没办法捕获到401
的状态码,然后查看控制台确实有401的状态码错误。当然这个情况不限于401的状态码,理论上40X和50X的状态码都会出现这种情况。下面我们先从一般使用nginx
处理跨域的方式说起
nginx跨域处理一般配置
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods *;
add_header Access-Control-Allow-Headers *;
if ($request_method = 'OPTIONS' ) {
return 204;
}
proxy_pass ***;
}
注意事项
乍一看上面的配置没什么问题,但是当服务器响应比如40x或者50x的状态码的时候,打开控制台你会发现还是会报跨域的错误,这时候会导致前端代码无法正确获取服务器响应状态码
add_header
官方的语法说明
Syntax: | add_header name value [always]; |
---|---|
Default: | — |
Context: | http , server , location , if in location |
Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). Parameter value can contain variables.
There could be several add_header
directives. These directives are inherited from the previous configuration level if and only if there are no add_header
directives defined on the current level.
If the always
parameter is specified (1.7.5), the header field will be added regardless of the response code.
这里主要注意两个点:
- 默认情况仅会在200等状态码的情况下给响应添加请求头
always
参数存在的话会忽略响应状态码,总是添加请求头
修改配置
location / {
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods * always;
add_header Access-Control-Allow-Headers * always;
if ($request_method = 'OPTIONS' ) {
return 204;
}
proxy_pass ***;
}
注意: 配置里面的“*”只是为了演示,实际的生产的项目应该根据实际情况配置。