CORS规则Chrome生效,Firefox仅部分文件类型访问失败求助
解决Cloudflare R2存储中.zip文件在Firefox的CORS预检失败问题
问题背景
在Cloudflare R2存储桶中存放了.zip和.json文件,通过arts.example.com子域名对外提供服务,供example.com页面跨域加载。目前Chrome、Vivaldi浏览器均可正常访问,但Firefox仅能加载.json文件,加载.zip文件时会出现CORS预检请求失败(返回403 Forbidden)的问题。
当前R2 CORS配置
用户当前的CORS配置存在格式错误,导致预检请求不被允许:
[ { "AllowedOrigins": [ "http://example.com", "https://example.com", "http://arts.example.com", "https://arts.example.com", "http://www.example.com", "https://www.example.com" ], "AllowedMethods": [ "GET", "HEAD", "POST" ], "AllowedHeaders": [ "Access-Control-Allow-Origin: http://example.com", "Access-Control-Allow-Origin: https://example.com", "Access-Control-Allow-Origin: http://arts.example.com", "Access-Control-Allow-Origin: https://arts.example.com", "Access-Control-Allow-Headers: Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With, User-Agent", "Content-Type: application/json", "Content-Type: application/zip", "Content-Type: application/octet-stream", "Access-Control-Allow-Credentials: true" ], "ExposeHeaders": [ "Content-Encoding", "Content-Type", "Cache-Control", "Content-Length" ], "MaxAgeSeconds": 300 } ]
Firefox请求响应对比
.zip文件预检请求与响应
预检OPTIONS请求包含range头,但R2返回403:
OPTIONS /onion/edz.zip HTTP/2 Host: arts.example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Access-Control-Request-Method: GET Access-Control-Request-Headers: range Referer: https://example.com/ Origin: https://example.com Connection: keep-alive Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-site Pragma: no-cache Cache-Control: no-cache TE: trailers
响应:
HTTP/2 403 Forbidden date: Mon, 11 Mar 2024 10:52:55 GMT content-type: text/html vary: Accept-Encoding cf-cache-status: DYNAMIC report-to: {"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v3?s=pscazcsNDW4dUrFlJWHnnN8j6gQo6xJY0im4g8voNvUp%2BS2OQ6QUzroL4zs%2BhE6xeN5bbGJZzuS4VHqQwBX7PCt9VeMjjfLCuQ20%2F7OibhJr2NSm1%2FD8yzhjAEJyA2Mf8Lk%3D"}],"group":"cf-nel","max_age":604800} nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800} server: cloudflare cf-ray: 862aff6d9ab00f4b-EWR content-encoding: br alt-svc: h3=":443"; ma=86400 X-Firefox-Spdy: h2
.json文件请求与响应
.json文件无预检请求,直接返回200并携带正确CORS头:
GET /onion/edz.json HTTP/2 Host: arts.example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Origin: https://example.com Connection: keep-alive Referer: https://example.com/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-site Pragma: no-cache Cache-Control: no-cache
响应:
HTTP/2 200 OK date: Mon, 11 Mar 2024 11:16:58 GMT content-type: application/json access-control-allow-origin: https://example.com etag: W/"01c68f37004a7409fffd99cd8f9d05f6" last-modified: Sat, 09 Mar 2024 16:34:21 GMT vary: Origin, Accept-Encoding access-control-expose-headers: Content-Encoding,Content-Type,Cache-Control,Content-Length cf-cache-status: DYNAMIC report-to: {"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v3?s=XXXXXXXXXXXXXXXXXXXXXXXXX"}],"group":"cf-nel","max_age":604800} nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800} server: cloudflare cf-ray: XXXXXXXX-EWR content-encoding: br alt-svc: h3=":443"; ma=86400 X-Firefox-Spdy: h2
已尝试的排查步骤
- 查阅Cloudflare文档,按文档操作后导致所有浏览器无法访问,希望不新增应用层解决
- 补充nginx location配置(存在多Origin头问题):
add_header "Access-Control-Allow-Origin" "https://example.com" always; add_header "Access-Control-Allow-Origin" "https://arts.example.com" always; add_header "Access-Control-Allow-Origin" "http://example.com" always; add_header "Access-Control-Allow-Origin" "http://arts.example.com" always; add_header "AllowMethods" "GET,POST,HEAD,OPTIONS" always; add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type" always;
- 排查Cloudflare WAF规则,尝试允许OPTIONS方法无效
- 排除WAF问题,推测预检请求未到达Cloudflare
- 迁移内容到其他S3主机,问题依然存在,排除Cloudflare端问题
- 普通nginx主机修正配置(修正Content-Type拼写错误、多Origin头问题)后,Firefox可正常加载.zip文件,但R2中仍无法加载,错误为“Cors Preflight Did Not Succeed”
解决方案
1. 修正R2 CORS配置
核心问题是当前配置中AllowedMethods未包含OPTIONS方法,且AllowedHeaders格式错误(填写了完整头内容而非头名称)。更新后的配置如下:
[ { "AllowedOrigins": [ "http://example.com", "https://example.com", "http://arts.example.com", "https://arts.example.com", "http://www.example.com", "https://www.example.com" ], "AllowedMethods": [ "GET", "HEAD", "POST", "OPTIONS" ], "AllowedHeaders": [ "range", "origin", "accept", "authorization", "content-length", "x-requested-with", "user-agent", "content-type" ], "ExposeHeaders": [ "Content-Encoding", "Content-Type", "Cache-Control", "Content-Length", "Accept-Ranges", "Content-Range" ], "MaxAgeSeconds": 300 } ]
- 添加OPTIONS方法:预检请求使用OPTIONS,必须明确允许才能通过
- 修正AllowedHeaders:仅填写请求头的名称,匹配Firefox预检中携带的
range等头 - 补充范围相关暴露头:因使用Range请求,需暴露
Accept-Ranges和Content-Range供前端处理响应
2. 修正nginx配置
nginx中不能同时添加多个Access-Control-Allow-Origin头,需动态匹配请求Origin,并正确处理OPTIONS请求:
add_header "Access-Control-Allow-Origin" $http_origin always; add_header "Access-Control-Allow-Methods" "GET,POST,HEAD,OPTIONS" always; add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Range" always; add_header "Access-Control-Expose-Headers" "Content-Encoding,Content-Type,Cache-Control,Content-Length,Accept-Ranges,Content-Range" always; # 直接处理OPTIONS预检请求,避免转发到R2 if ($request_method = OPTIONS) { return 204; }
3. 验证步骤
- 更新R2 CORS配置后等待几分钟生效
- 重启nginx或重新加载配置
- 清除Firefox缓存后测试,确认预检请求返回200,.zip文件可正常加载
内容的提问来源于stack exchange,提问作者Stonecraft
相关产品推荐
相关产品推荐

