alias映射静态资源时跨域头失效,根本原因是add_header不继承、不生效于alias作用域内,必须在alias所在location块中显式配置所有cors响应头,并单独拦截options预检请求返回204及完整跨域头。

用 alias 映射静态资源时跨域头失效,根本原因在于 Nginx 的 add_header 指令**不继承、不生效于 alias 作用域内**——它只对 proxy_pass 或 root 下的常规响应起作用,而 alias 是路径重写后直接文件服务,响应头需显式配置在对应 location 块中,且必须覆盖所有可能触发的响应路径(包括 OPTIONS 预检)。
确保跨域头写在 alias 所在的 location 块里
add_header 是“响应阶段指令”,只对当前 location 生成的响应生效。若把跨域头写在 server 级或上级 location,它不会自动透传到 alias 匹配的 location 中。
- ❌ 错误写法(server 级添加,对 alias 无效):
add_header Access-Control-Allow-Origin *;
location /static/ {
alias /data/assets/;
}
}
- ✅ 正确写法(头必须紧贴 alias location):
alias /data/assets/;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, 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";
}
必须单独处理 OPTIONS 预检请求
浏览器加载字体(.woff2/.ttf)、图片或带自定义头的资源时,会先发 OPTIONS 请求。而 alias 不代理、不转发,Nginx 默认对 OPTIONS 返回 204 或 405,此时跨域头根本不会发出。
- 在 alias location 内加 if 判断,拦截并返回 204(或 200)+ 全套 CORS 头
- 注意:不能只靠 add_header,必须 return 显式响应
alias /var/www/fonts/;
# 处理预检
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, 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 86400;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
# 正常 GET 响应头
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
}
避免多 location 冲突或重复头
如果同一路径被多个 location 匹配(比如正则 location 和前缀 location 重叠),Nginx 会选择最精确匹配的那个,但 add_header 可能被覆盖或遗漏;更严重的是,若某处写了两次 Access-Control-Allow-Origin,Chrome 会报错:"header contains multiple values"。
- 检查是否在 server 块、上级 location、或 include 文件中重复添加了相同 header
- alias 所在 location 必须是唯一且明确匹配的,建议用前缀匹配(如
location ^~ /static/)避免正则干扰 - 字体等二进制资源建议单独拆出 location(如
location ~* \.(woff2|ttf|eot)$),并独立配 CORS
验证与调试技巧
别只看浏览器控制台报错,要确认实际响应头是否发出:
- 用 curl 模拟 OPTIONS 请求:
curl -X OPTIONS -H "Origin: https://example.com" -I http://your-domain.com/fonts/icon.woff2 - 检查返回中是否有
Access-Control-Allow-Origin,且值非空、无重复 - 清除浏览器缓存(特别是预检响应会被缓存),或用隐身窗口测试
- 开启 Nginx error_log debug 级别,观察 location 匹配日志,确认请求确实进了你写的那个 alias 块











