add_header默认仅对2xx/3xx响应生效,4xx/5xx错误响应不携带CORS头,导致跨域失败;加always参数后,Access-Control-Allow-Origin等头在所有状态码(含404、500)下均强制发送。

直接在 add_header 指令末尾加上 always 参数,就能让跨域响应头(如 Access-Control-Allow-Origin)出现在所有 HTTP 状态码的响应中,包括 404、500、502 等异常状态。
为什么默认不生效
Nginx 的 add_header 默认只对“成功类”状态码生效,比如 200、201、204、301、302 等。而 404、500、502、503 这些错误响应不会自动携带你配置的 CORS 头,浏览器收到后就因缺少 Access-Control-Allow-Origin 而报跨域错误——即使接口路径根本不存在或后端崩了,前端依然需要能读取响应内容做友好提示。
正确写法:必须加 always
把原来这样写:
✘ 错误(404/500 不带跨域头)add_header Access-Control-Allow-Origin *;
改成这样:
✔ 正确(所有状态码都生效)add_header Access-Control-Allow-Origin * always;
其他 CORS 头也同理,例如:
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;-
add_header Access-Control-Allow-Credentials "true" always;(注意:此时Origin不能为*,需指定具体域名)
配合自定义错误页时的注意事项
如果你同时配置了 error_page 404 /404.html; 或 error_page 500 /50x.html;,要确保这些错误页面的 location 块里也加了 always:
例如:
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET" always;
}
否则,Nginx 在返回自定义错误页时会走这个 location 分支,而该分支若没加 always,仍可能丢失跨域头。
验证是否生效
用 curl 模拟请求,强制触发 404 或 500:
-
curl -I -X GET https://your-domain.com/nonexistent-path—— 查看响应头是否含Access-Control-Allow-Origin - 访问一个故意抛 500 的接口(如后端已宕机),在浏览器开发者工具 Network 标签中检查响应头
只要看到对应头存在,说明 always 已起作用。











