nginx 跨域 CORS
注意
!> 如果后端例如 FastApi, Webhook 等已经配置过跨域, 那么 nginx 将无需再次配置跨域设置.
因为 Nginx 和服务端均对 Access-Control-Allow-Origin 标头设置了值,导致请求未通过浏览器的 CORS 策略,从而被浏览器拦截了响应结果。在平时项目开发中,尽量协调好一端去配置跨域策略,避免因重复设置标头而造成请求失败的问题。
配置
nginx
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE' always;
add_header 'Access-Control-Allow-Headers' '*' always;
add_header 'Access-Control-Max-Age' 1728000 always;
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain; charset=utf-8';
解决 OPTION 重复请求
nginx
if ($request_method = 'OPTIONS') {
return 204 ;
}
多域名跨域
if (不推荐)
nginx
server {
set $allow_origin "";
if ( $http_origin ~ '^https?://(www|m).sundayle.com' ) {
set $allow_origin $http_origin;
}
location /{
add_header 'Access-Control-Allow-Origin' $allow_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,X_Requested_With,If-Modified-Since,Cache-Control,Content-Type';
if ($request_method = 'OPTIONS') {
return 204;
}
...
}
map (建议)
nginx
map $http_origin $allow_origin {
default "";
"~^(https?://localhost(:[0-9]+)?)" $1;
"~^(https?://127.0.0.1(:[0-9]+)?)" $1;
"~^(https?://192.168.10.[\d]+(:[0-9]+)?)" $1;
"~^https://www.sunday.com" https://www.sundayle.com;
"~^https://m.sundayle.com" https://m.sundayle.com;
"~^(https?://[\w]+.open.sundayle.com)" $1;
#"~^(https?://([\w]+.)?[\w]+.open.sundayle.com)" $1; #允许一级和二级域名
}
server {
location /{
add_header 'Access-Control-Allow-Origin' $allow_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,X_Requested_With,If-Modified-Since,Cache-Control,Content-Type';
if ($request_method = 'OPTIONS') {
return 204;
}
...
}
其他更多判断
nginx
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
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-Max-Age' 1728000; # 20days
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' 'https://www.sundayle.com';
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' 'https://www.sundayle.com';
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';
}
}