1问题背景
公司项目调试期间,浏览网页的时候可能会浏览失败,调出F12查看报错,会看到以下报错信息 No 'Access-Control-Allow-Origin' header is present on the requested resource.Origin
出现此类报错的时候说明出现了跨域问题
跨域的意思是使用js获取数据时,涉及到的两个url只要协议、域名、端口有任何一个不同,都被当作是不同的域,相互访问就会有跨域问题。
例如你的web域名是www.a.com.cn,登录的时候会调用www.b.cn上面的资源,此时就会出现跨域
2解决方法
拿以上案例来说,a域名要去请求b域名的资源,那么b域名的nginx的配置中,就要设置允许跨域访问(注意:此方法仅适用于使用nginx的web项目)。
方法1:通用配置
在nginx 的b域名的server location配置下面增加如下配置
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE';
配置介绍
1)add_header 'Access-Control-Allow-Origin' '*';#允许指定的域名访问所在域的资源,比如允许a访问b的资源,那就就在b的location里面写上add_header 'Access-Control-Allow-Origin' 'www.a.com.cn',
后面的域名可以用*号代替,*号代表所有的域。假如说我们还有c域名,d域名等等的n个域也想访问b的资源的时候,我们就没办法手动配置那么多的域名了,所以我们就用*号来代表所有的域
2)add_header 'Access-Control-Allow-Credentials' 'true';#表示是否允许发送Cookie,该字段是可选的,默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,
3)add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';#服务器支持的所有头信息字段,后面可添加的字段很多,我们可以多添加一点,防止有些头信息字段不支持,后可添加的字段详细配置可参考https://www.w3.org/TR/cors/#access-control-allow-headers-response-header
4)add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE';#服务器支持的所有跨域请求的方法,其实方法无非就那么几个,get,post,options,put,delete等等,但是还是要跟开发的确认好,防止有些方法不支持
一般来说,nginx加上这些配置就可以解决跨域问题了,如果还是不行的话,我们就尝试下面这种方法
方法2:特殊配置
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep- Alive,User- Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content- Type,Authorization,token';
return 204;}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,token';}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow- Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,token';}
if ($request_method = 'PUT') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,token';}
if ($request_method = 'DELETE') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,token';}
上面的配置中,不同的请求方法会有不同的处理策略,根绝请求方法的不同可以根据自己的实际情况去做对应调整。
配置好之后,就不会再有跨域的问题了
3常见问题
如果浏览器报错说跨域的'Access-Control-Allow-Headers’缺少字段,比如缺少Authorization,那我们就在其后面添加Authorization
如果报错The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.,说明这个add_header 'Access-Control-Allow-Origin' '*';配置项重复了
这个配置项要么配置在代码里面,要么配置在nginx里面,不能俩个位置同时出现此配置
4参考网址
1)https://www.w3.org/TR/cors/
2)http://www.ruanyifeng.com/blog/2016/04/cors.html
3)https://www.cnblogs.com/sunmmi/articles/5956554.html