橙宝书
实战配方

配方:R2 生产交付、跨域与私有上传

分清自定义域名、CORS 与预签名 URL 的职责,把图片、PDF 和附件安全交付到生产环境。

编辑与核验:橙宝书编辑团队 ·

RECIPE · 生产交付约 28 分钟R2 · 浏览器 · 自定义域名

先给结论

公开读取走自定义域名,浏览器直传私有 bucket 时由服务端生成短时预签名 URL,再用精确 CORS 放行你的应用域名。r2.dev 只用于非生产测试;预签名 URL 使用 R2 的 S3 API 域名,不能换成自定义域名。

三个能力不要混用

能力解决什么不解决什么
自定义域名公开读取、缓存,以及 WAF、Access、Bot 等 Cloudflare 能力不替代私有对象授权
CORS允许指定浏览器来源读取响应或发起上传不是认证;非浏览器客户端不受它保护
预签名 URL在有效期内授权一个具体 S3 API 操作不是永久公开链接,也不能隐藏拿到 URL 的人

公开素材

站点图片、公开下载与发布后的 CMS 媒体:使用自定义域名,并把缓存与安全策略放在这个入口。

私有上传

SaaS 附件、图片转换输入与 PDF 文件:应用先鉴权,再由服务端签发短时 PUT URL。

私有下载

服务端检查用户、租户与对象 key 后,签发短时 GET URL;对象名不要包含不必要的个人信息。

生产落地

先画出访问矩阵

列出每类对象的读取者、写入者、是否公开、允许的 Content-Type、最大尺寸和保留期。不要让同一个 bucket 同时承担“永久公开素材”和“敏感临时文件”,除非你已设计清晰前缀与授权边界。

给公开读取绑定自定义域名

在 R2 bucket 的设置中绑定已由当前 Cloudflare 账号管理的域名。验证自定义域名后,如果不再需要测试入口,关闭 r2.dev;否则读者仍可能绕过只配置在自定义域名上的保护。

只读验证
curl -I https://media.example.com/public/sample.webp

检查状态码、Content-TypeCache-ControlETagCF-Cache-Status,不要只确认“浏览器能打开”。

为浏览器配置最小 CORS

来源必须是精确的 scheme://host[:port],不能带路径。开发域名与生产域名分别列出,不要为了省事使用 * 允许私有上传。

R2 CORS 示例
[
  {
    "AllowedOrigins": ["https://app.example.com"],
    "AllowedMethods": ["GET", "PUT"],
    "AllowedHeaders": ["Content-Type"],
    "ExposeHeaders": ["ETag"],
    "MaxAgeSeconds": 3600
  }
]

自定义域名已经缓存过旧的 CORS 响应时,修改配置后还要清理对应缓存对象,再重新发起预检请求。

只在服务端生成预签名 URL

签名前先验证登录状态、租户、对象 key、操作类型、Content-Type 与业务配额。URL 应尽量短效,并通过 HTTPS 返回;R2 预签名 URL 最长可设置为 7 天,但这不是推荐默认值。它支持 GETHEADPUTDELETE,不支持 S3 的 HTML form POST 上传。

用真实浏览器来源验证两条分支

验证 CORS 预检
read -r -s -p '粘贴短时预签名 URL:' R2_SIGNED_URL
curl -i -X OPTIONS "$R2_SIGNED_URL" \
  -H 'Origin: https://app.example.com' \
  -H 'Access-Control-Request-Method: PUT' \
  -H 'Access-Control-Request-Headers: content-type'
unset R2_SIGNED_URL

使用服务端刚刚生成、尚未过期的 URL。允许来源应返回匹配的 CORS 头;把 Origin 改成未授权域名后,不应得到同样的放行结果。最后在真实应用中上传一个小文件,并验证错误 Content-Type、过期 URL 与越权 key 都失败。

预签名 URL 是 bearer token

任何拿到 URL 的人都能在有效期内执行被签名的操作。不要写入日志、分析事件或工单正文;不要在浏览器生成签名;不要把账号级 R2 密钥交给客户端。

发布与回退清单

  • 先用测试 bucket 和测试域名验证,再配置生产 bucket。
  • 保留旧读取入口,直到新域名的命中、错误率和下载完整性稳定。
  • 若上传失败,先停止签发新 URL,不要立即删除旧对象。
  • 回退时恢复旧应用入口;CORS、DNS 或缓存规则一次只撤回一项并重新验证。

准备迁移已有对象时继续看 R2 迁移手册;先比较成本模型可读 R2、S3、OSS 与 B2 对比

官方来源

这篇内容帮你完成目标了吗?

内测反馈只在当前浏览器生成,不会自动上传。

本页目录