nginx配置允许跨域白名单V2
1.核心判断逻辑
为了避免代码冗余,可以把这套判断逻辑写成一个独立的文件(例如 cors_check.conf),然后在需要的 location 里 include 它:
文件:conf.d/cors_check.conf
# --- 跨域精准拦截逻辑 ---
set $cors_check "";
# 步骤A: 检查是否存在 Origin 头部(判断是否为跨域)
if ($http_origin != "") {
set $cors_check "is_cors";
}
# 步骤B: 检查是否不在白名单内 ($allow_cors 来自外层的 map 定义)
if ($allow_cors = 0) {
set $cors_check "${cors_check}_deny";
}
# 步骤C: 只有跨域且不在白名单时,返回带说明的 403
if ($cors_check = "is_cors_deny") {
add_header 'Content-Type' 'application/json; charset=utf-8';
# 返回详细 JSON,方便前端定位问题
return 403 '{"status": 403, "error": "CORS_POLICY_BLOCKED", "reason": "Nginx: The origin [$http_origin] is not in the whitelist.", "suggestion": "Please contact OPS to add this domain to the allow-list."}';
}
2.项目中的完整应用示例
在nginx.conf中,按照以下结构组织代码:
# 【第一步:全局白名单定义】
http {
# --- map 必须在这里,定义在所有 server 之前 ---
map $http_origin $allow_cors {
default 0;
"https://zbc.cn" 1;
"https://abc" 1;
"http://192.168.1.85:8080" 1;
# ... 其他白名单
}
server {
listen 80;
server_name your-project.com;
# 【第二步:应用到具体的 Location】
location /prod-api {
# 引入刚才创建的拦截逻辑
include conf.d/cors_check.conf;
# 如果通过了拦截,处理 OPTIONS 预检请求(可选但推荐)
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $http_origin always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' '*' always;
return 204;
}
# 1. 如果后端有配置*则隐藏后端发出的跨域头(防止冲突)
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Credentials';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
# 业务转发
proxy_pass http://192.168.98.100:8301;
# 成功通过后,必须给响应补上跨域头,否则浏览器还是会拦截
add_header 'Access-Control-Allow-Origin' $http_origin always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' '*' always;
}
}
}
说明
1.错误隔离:如果是因为目录权限、IP黑名单导致的 403,会返回 Nginx 默认的错误页;只有因为 Origin 不在白名单 导致的 403,才会返回那段 JSON 提示。
2.自助诊断:JSON 信息里直接输出了 $http_origin。当开发人员找你时,你只需要问他:“报错信息里的 origin 是哪个?” 就能立刻判断是没配、还是协议(http/https)配错了。
3.标准化:通过 include 方式,你以后在其他 location 甚至其他 server 块里,只需要一行代码就能复用这套逻辑。
本帖子也是纯手工制作,转载请标明出处-----------burukku(づ。◕ᴗᴗ◕。)づ

浙公网安备 33010602011771号