Nginx通过map指令动态设置Access-Control-Allow-Origin实现多环境跨域控制:开发环境允localhost及dev域名,测试环境限test域名,生产环境严格白名单校验,禁用*以保障Credentials安全。

通过 Nginx 配置实现 API 接口在不同环境下的跨域切换,核心在于根据请求来源(如域名、请求头或路径)动态设置 Access-Control-Allow-Origin 等 CORS 响应头,而非硬编码单一值。关键不是“开关跨域”,而是“按需放行”,兼顾安全性与灵活性。
区分环境的方式:用变量控制跨域策略
Nginx 本身不内置“开发/测试/生产”环境标识,需借助外部条件判断并赋值变量。常用方式有:
-
基于 Host 头识别:例如开发环境调用
api.dev.example.com,测试环境为api.test.example.com,Nginx 可用map指令映射对应允许的前端源 -
基于请求头识别:前端在开发时主动带上自定义头(如
X-Env: dev),Nginx 判断该头值后启用宽松策略(仅限可信内网或本地调试) -
基于 IP 或 referer 限制:例如只对
127.0.0.1、localhost或内部测试域名放行*,其余环境走白名单
安全地支持多源:避免滥用 Access-Control-Allow-Origin: *
生产环境绝不能无条件返回 *(尤其当 Credentials 为 true 时会直接被浏览器拒绝)。正确做法是:
- 维护一个可信前端域名白名单(如
dev.example.com、test.example.com、app.example.com) - 用
map将请求的$http_origin映射为允许值,匹配则返回对应 origin,不匹配则不返回该 header 或返回空 - 配合
add_header Access-Control-Allow-Credentials "true"时,Access-Control-Allow-Origin必须为具体域名,不可为*
完整可复用的 Nginx 配置示例
以下配置实现了:开发时 localhost 允许任意 origin + credentials;测试环境仅允 test 域名;生产环境严格白名单校验:
map $http_origin $cors_origin {
default "";
"~^https?://localhost(:[0-9]+)?$" "$http_origin";
"~^https?://dev\.example\.com$" "$http_origin";
"~^https?://test\.example\.com$" "$http_origin";
"~^https?://app\.example\.com$" "$http_origin";
}
<p>server {
listen 80;
server_name api.example.com;</p><pre class="brush:php;toolbar:false;">location /api/ {
proxy_pass http://backend;
# 动态设置跨域头
add_header 'Access-Control-Allow-Origin' $cors_origin always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Env' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
# 处理预检请求
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;
}
}
}
调试与验证要点
上线前务必验证实际响应头是否符合预期:
- 用
curl -H "Origin: https://dev.example.com" -I https://api.example.com/api/user检查是否返回匹配的Access-Control-Allow-Origin - 确认开发环境调用时,
Origin: http://localhost:3000能被正确识别并返回该值 - 检查浏览器开发者工具 Network 面板中响应头,特别注意
Access-Control-Allow-Credentials和Access-Control-Allow-Origin是否同时存在且兼容 - 禁用某条
map规则后,对应 origin 应完全收不到 CORS 头(即默认不跨域)
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











