在现代 Web 开发中,如果你试图从前端(例如 https://your-site.com)直接上传文件到对象存储,或者通过 XHR/Fetch 加载存储桶中的资源,你大概率会遇到红色的 CORS Policy Error

本文将详细介绍如何正确配置 Backblaze B2 和 Cloudflare R2 的跨域规则。特别是 B2,由于其 Web UI 功能有限,我们需要动用命令行工具(CLI)来实现完美的混合兼容配置。


第一部分:Backblaze B2 配置 (硬核 CLI 模式)

Backblaze B2 的网页管理界面虽然可以创建存储桶,但在 CORS 规则的细粒度控制上非常简陋。为了实现同时支持 S3 协议B2 原生 API 的跨域访问,必须使用 B2 CLI 工具。

1. 环境准备

首先,确保你安装了官方的 B2 命令行工具。 如果你有 Python 环境:

pip install b2

2. 授权登录

使用你的 Key ID 和 Application Key 进行授权。 (注:请务必保护好你的 Key,不要泄露给他人)

# 格式: b2 authorize-account <KEY_ID> <APPLICATION_KEY>
b2 authorize-account <Key ID> <Application Key>

提示:执行成功后,CLI 会缓存授权 Token,后续操作无需重复登录。

3. 编写 CORS 配置文件 (b2-cors.json)

这是最关键的一步。为了兼容性,建议同时开启 S3 相关的操作和 B2 原生的操作权限。

创建一个名为 b2-cors.json 的文件,内容如下(参考实际生产环境配置):

[
  {
    "corsRuleName": "allow-all-apps",
    "allowedOrigins": [
      "https://cloud.yangyongsheng.dpdns.org",
      "https://cloud.yysresume.work",
      "http://localhost:3000"
    ],
    "allowedHeaders": [
      "*"
    ],
    "allowedOperations": [
      "s3_put",
      "s3_get",
      "s3_head",
      "s3_post",
      "s3_delete",
      "b2_download_file_by_name",
      "b2_upload_file"
    ],
    "exposeHeaders": [
      "ETag"
    ],
    "maxAgeSeconds": 3600
  }
]

配置详解:

  • allowedOrigins: 允许跨域请求的来源域名。一定要包含协议头(https://)。开发环境通常需要加上 http://localhost:3000
  • allowedOperations: 这里是精华所在。
    • s3_*: 允许通过 S3 兼容协议(如 AWS SDK, rclone)进行操作。
    • b2_*: 允许通过 B2 原生 API 进行操作。
    • 为什么两个都要写? 有些前端库默认使用 S3 协议上传,但部分下载链接可能是 B2 原生链接,混合配置能避免很多奇怪的 403 错误。
  • exposeHeaders: 允许前端 JavaScript 获取的响应头。通常需要 ETag 来验证文件完整性。
  • maxAgeSeconds: 浏览器缓存 CORS 预检请求(OPTIONS)的时间,3600 秒意味着 1 小时内浏览器不需要再次询问服务器是否允许跨域,能提高性能。

4. 应用规则

使用 b2 update-bucket 命令将规则应用到指定的存储桶(例如 yyscloud)。

这里需要注意存储桶的类型,通常设为 allPrivate(配合应用鉴权访问)或 allPublic

# 将 b2-cors.json 的内容作为参数传入
b2 update-bucket yyscloud allPrivate --cors-rules "$(cat b2-cors.json)"

验证是否成功: 执行以下命令查看存储桶详情:

b2 get-bucket yyscloud

如果在返回的 JSON 中看到了 corsRules 字段且内容正确,即表示配置成功。


第二部分:Cloudflare R2 配置 (现代化 Dashboard 模式)

Cloudflare R2 的优势在于无需支付出口流量费,且与 Cloudflare CDN 完美集成。R2 的配置更符合 S3 标准,且可以通过图形界面完成。

1. 进入配置页面

  1. 登录 Cloudflare Dashboard。
  2. 点击左侧菜单的 R2
  3. 点击你需要配置的存储桶名称。
  4. 进入 Settings (设置) 选项卡。
  5. 向下滑动找到 CORS Policy (CORS 策略) 部分,点击 Add/Edit CORS Policy

2. 输入配置 JSON

R2 使用标准的 S3 CORS JSON 格式(与 B2 的 JSON 略有不同,不需要指定具体的操作名称如 s3_put,而是使用 AllowedMethods)。

推荐配置如下:

[
  {
    "AllowedOrigins": [
      "https://cloud.yangyongsheng.dpdns.org",
      "https://cloud.yysresume.work",
      "http://localhost:3000"
    ],
    "AllowedMethods": [
      "GET",
      "PUT",
      "POST",
      "HEAD",
      "DELETE"
    ],
    "AllowedHeaders": [
      "*"
    ],
    "ExposeHeaders": [
      "ETag"
    ],
    "MaxAgeSeconds": 3600
  }
]

3. 保存并生效

点击保存后,规则通常在几秒钟内生效(全球边缘节点同步可能需要稍多一点时间,但通常很快)。


第三部分:B2 与 R2 的 CORS 差异总结

特性 Backblaze B2 Cloudflare R2
配置方式 推荐 CLI (Web UI 功能缺失) Web Dashboard 或 Terraform
规则格式 B2 专有格式 (区分 s3_b2_ 操作) 标准 S3 格式 (GET, PUT 等)
生效速度 几乎实时 极快 (依赖边缘节点更新)
坑点 容易忘记添加 s3_ 开头的操作导致 SDK 报错 如果使用自定义域名,需确保 Cloudflare 里的缓存规则没有覆盖 CORS 头

常见问题排查 (Troubleshooting)

  1. 配置了规则还是报 CORS 错误?

    • 清除缓存:浏览器会缓存旧的 CORS 结果。尝试在开发者工具中勾选 "Disable Cache" 或清空缓存。
    • 检查 Origin:浏览器发送的 Origin 头必须严格匹配 AllowedOrigins 中的字符串(注意末尾不要多斜杠,注意 http 和 https 的区别)。
  2. Backblaze B2 使用 S3 SDK 上传失败?

    • 检查 b2-cors.json 中是否包含了 "s3_put""s3_post"。如果只写了 "b2_upload_file",S3 SDK 是无法工作的。
  3. 如何允许所有网站访问?

    • AllowedOrigins 设置为 ["*"]警告: 这样做有安全风险,意味着任何网站都可以通过 AJAX 请求你的资源(如果是私有桶配合签名 URL 则问题不大,如果是公开桶则容易被盗链)。

通过以上步骤,你可以完美解决 Backblaze B2 和 Cloudflare R2 的跨域访问问题,为你的图床、网盘或 Web 应用提供坚实的存储后端支持。