Nginx配置Access-Control-Allow-Origin后AJAX 301响应仍报CORS跨域错误
问题产生原因
- 你配置的
Access-Control-Allow-Origin响应头仅作用于匹配.php后缀的location块,而AJAX请求拿到的301跳转响应是Nginx在进入该location块之前返回的,不会执行该块内的add_header逻辑,自然不会携带CORS相关头。 - 浏览器直接访问地址时,会自动跟随域名规范化、补全路径斜杠、HTTP转HTTPS这类301跳转,你看到的带CORS头的响应是跳转完成后命中php location返回的200结果;但跨域场景下浏览器会校验每一次响应的CORS头,第一次301响应没带合法CORS头时会直接拦截请求,不会继续执行跳转逻辑。
- Nginx的
add_header指令存在继承规则:当前配置块只要存在任意add_header配置,就不会继承上层块的add_header规则。你把CORS头单独配置在php location块中,其他返回301、4xx、5xx响应的配置块没有对应头配置,就会出现跨域头缺失的问题。
修复方案
- 先修正AJAX请求地址,从根源避免不必要的301跳转:核对请求地址的协议(HTTP/HTTPS)、域名格式(是否带www)、路径后缀(是否缺末尾斜杠),直接填写最终能返回200响应的地址,消除触发301的前置条件。
- 调整Nginx配置层级,把CORS相关头移到对应
server块下,保证所有响应(包括跳转、错误页响应)都能携带合法跨域头,同时单独处理OPTIONS预检请求,参考配置如下:
server { listen 443 ssl; server_name 你的服务域名; # 省略其他server基础配置(证书、根目录、日志路径等) # CORS配置放在server层级,对所有响应生效 add_header Access-Control-Allow-Origin '*' always; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always; add_header Access-Control-Allow-Headers 'Content-Type, X-Requested-With, Authorization' always; # 跨域预检请求直接返回204,不需要转发到php处理 if ($request_method = 'OPTIONS') { return 204; } location ~ \.php$ { include /var/ini/nginx/fastcgi.conf; fastcgi_pass php; fastcgi_param SCRIPT_FILENAME $document_root/index.php; # 此处无需重复配置CORS头,会自动继承server层配置 } }
- 执行
nginx -t校验配置语法无误后,运行nginx -s reload重载配置;测试前清空浏览器缓存,避免之前缓存的301跳转规则影响验证结果。
内容的提问来源于stack exchange,提问作者clarkk
相关产品推荐
相关产品推荐

