跨域资源共享(CORS)是现代浏览器安全策略的一部分,Nginx可以通过配置响应头来解决跨域问题。以下是完整的配置方案:
基础跨域配置
在Nginx配置文件的 server
或 location
块中添加以下指令:
location / {
# 允许所有域名跨域访问(生产环境应限制为具体域名)
add_header 'Access-Control-Allow-Origin' '*';
# 允许的请求方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
# 允许的请求头
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
# 预检请求(OPTIONS)缓存时间
add_header 'Access-Control-Max-Age' 1728000;
# 允许浏览器在跨域请求中携带Cookie
add_header 'Access-Control-Allow-Credentials' 'true';
# 处理OPTIONS预检请求
if ($request_method = 'OPTIONS') {
return 204;
}
}
生产环境推荐配置
map $http_origin $cors_origin {
default "";
"~^https://(www\.)?yourdomain\.com$" $http_origin;
"~^https://(.*\.)?yourotherdomain\.com$" $http_origin;
}
server {
location /api/ {
# 动态设置允许的源
add_header 'Access-Control-Allow-Origin' $cors_origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With';
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range';
add_header 'Access-Control-Allow-Credentials' 'true';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# 你的其他代理配置...
proxy_pass http://backend;
}
}
常见问题解决方案
-
多个域名配置:
map $http_origin $cors_origin { default ""; "~^https://(www\.)?domain1\.com$" $http_origin; "~^https://(www\.)?domain2\.com$" $http_origin; }
-
携带Cookie问题:
- 必须指定具体域名(不能是
*
) - 必须设置
Access-Control-Allow-Credentials: true
- 前端需要设置
withCredentials: true
- 必须指定具体域名(不能是
-
自定义头问题:
add_header 'Access-Control-Allow-Headers' 'X-Custom-Header, Authorization';
-
Vue/React开发环境代理:
location /api { proxy_pass http://localhost:8080; proxy_set_header Host $host; # 跨域头设置... }
配置测试方法
-
检查Nginx配置语法:
sudo nginx -t
-
重载Nginx配置:
sudo nginx -s reload
-
使用curl测试:
curl -I -X OPTIONS http://yourdomain.com/api -H "Origin: http://test.com"
-
浏览器开发者工具检查响应头
注意事项
- 生产环境不要使用
Access-Control-Allow-Origin: *
和Access-Control-Allow-Credentials: true
同时存在 - 对于简单请求(GET/POST/HEAD)和预检请求(OPTIONS)都要正确处理
- 缓存控制头不要覆盖CORS头
- 使用HTTPS时确保所有来源也是HTTPS
正确配置CORS可以确保你的API安全地支持跨域访问,同时防止CSRF等安全问题。