浏览器对于非简单的请求,会分两次应答。
第一次 预检请求(method:OPTIONS),主要验证来源是否合法,并返回允许的 Header 等。
第二次才是真正的 HTTP 应答。所以服务器必须处理 OPTIONS 应答,OPTIONS 请求要做 204 处理。
以下为需在 nginx 中配置的几个参数:
Access-Control-Allow-Origin(必含):允许的域名,只能填通配符或者单域名
Access-Control-Allow-Methods(必含):允许跨域请求的 http 方法
Access-Control-Allow-Headers:返回支持的 http 请求头
Access-Control-Allow-Credentials(可选):标志着当前请求是否包含 cookies 信息,布尔值。只有一个可选值:true,如果不包含 cookies,请略去该项,而不是填 false。这一项与XmlHttpRequest2 对象当中的 withCredentials 属性应保持一致,即 withCredentials 为true时该项也为 true;withCredentials为false时,省略该项不写。反之则导致请求失败。
Access-Control-Max-Age(可选):以秒为单位的缓存时间,用于缓存预检请求。
看看配置文件中:
add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; add_header Access-Control-Allow-Credentials 'true'; add_header Access-Control-Allow-Headers 'Accept, Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' *; add_header 'Access-Control-Max-Age' 1728000; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Accept, Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 200; }
这个配置代码放在 http 代码块中。
如果是options请求的时候,我们返回204 或者200
nginx非简单请求返回”405 Method Not Allowed”或者403,需要进行单独的判断,判断是否options 请求,如果是 ,则默认返回 200 的状态码
或者这样添加:
if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'Content-Type'; return 200; } 或 add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'Content-Type'; #在location处添加以下内容 if ($request_method = 'OPTIONS') { return 200; } #是否允许cookie携带 add_header Access-Control-Allow-Credentials 'true';
添加以上代码后,重新启动nginx的配置,即可访问。
解决办法
由于我博客被CORS策略阻止的只有字体,因此我只需要nginx配置字体跨域就行了。就不用配置其它跨域了。毕竟:Access-Control-Allow-Origin * 跨域是很危险的。
注意:nginx.conf配置好了,一定要重启nginx。
nginx中Access-Control-Allow-Origin字体跨域配置
方法:
location ~* \.(eot|ttf|woff|woff2|svg)$ { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers X-Requested-With; add_header Access-Control-Allow-Methods GET,POST,OPTIONS; }
以上nginx.conf这样就可以实现GET,POST,OPTIONS的跨域请求的支持,也可以 add_header Access-Control-Allow-Origin --指定允许的url;
nginx中Access-Control-Allow-Origin 其它跨域配置
示例:
#
# 用于nginx的开放式CORS配置
#
location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # 自定义标题和标题各种浏览器*应该*可以,但不是 # add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; # # 告诉客户这个飞行前信息有效期为20天 # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } }