使用XHR向子域API传凭证遇CORS预检重定向错误
跨域XHR上传图片的CORS预检问题解决方案
问题核心
跨域使用XHR上传multipart/form-data格式图片时,浏览器发送的OPTIONS预检请求因未携带凭证触发鉴权重定向,而CORS规则明确禁止预检请求重定向,导致请求被拦截。移除API鉴权后请求正常,说明问题出在预检请求的凭证传递与鉴权处理上。
解决方案
1. 在Nginx层直接处理OPTIONS预检请求
将OPTIONS请求与业务请求分离,避免预检请求进入后端触发鉴权逻辑,直接返回符合要求的CORS响应头:
# 处理OPTIONS预检请求 if ($request_method = OPTIONS) { add_header "Access-Control-Allow-Origin" "https://example.com" always; add_header "Access-Control-Allow-Credentials" "true"; add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS"; # 根据实际请求头添加允许的字段,比如Authorization、Content-Type等 add_header "Access-Control-Allow-Headers" "Content-Type, Authorization"; return 204; } # 业务请求的CORS头配置 add_header "Access-Control-Allow-Origin" "https://example.com" always; add_header "Access-Control-Allow-Credentials" "true";
2. 调整XHR配置,避免不必要的预检触发
- 不要手动设置
Content-Type头:FormData会自动生成带边界的multipart/form-data头,手动设置会导致浏览器判定为非简单请求,强制发送预检 - 确认没有添加自定义请求头:任何超出简单请求范围的头都会触发预检,若必须添加,需在Nginx的
Access-Control-Allow-Headers中声明
3. 为什么Fetch能正常工作?
Fetch请求若满足简单请求条件(POST方法、Content-Type为multipart/form-data、无自定义头),浏览器会直接发送带凭证的请求,不会触发OPTIONS预检,因此能绕过预检重定向的问题。而XHR可能因浏览器的细微差异,或隐式配置触发了预检流程,导致暴露问题。
内容的提问来源于stack exchange,提问作者Tony Merryfield
相关产品推荐
相关产品推荐

