Zhanbo's Blog
Back to home

Typora + PicGo + Cloudflare R2 图床上传成功却裂图:一场 URL 拼接的踩坑实录

Pitfall Notes
2026-07-19
3 min read
0 reads

Typora中借助PicGo上传图片至Cloudflare受阻,本文通过正确拼接URL,上传图片并在本地正确输出。

TyporaPicGoCloudflare R2图床Markdown踩坑记录

今天下午整理博客时,突然发现 Typora 里所有通过 PicGo 上传到 Cloudflare R2 的图片全部变成了裂图。浏览器直接访问图片链接返回 403,但 PicGo 的上传日志显示 success。经过一番排查,最后发现坑在 PicGo 的 outputURLPattern 配置上——不是图床挂了,是 URL 根本没拼对。

症状:上传成功,Typora 不渲染

事情是这样的:

  • PicGo 里配置了 Cloudflare R2(通过 S3 兼容 API)。
  • 点击上传,PicGo 提示成功,返回了一个链接。
  • 把链接贴进 Typora,结果只显示一行蓝色文字,或者干脆是裂图。

我下意识以为是图床挂了,因为返回的域名长这样:

https://xxxassets.hashcode.r2.cloudflarestorage.com/2026/07/xxx.png

但诡异的是,我用 Cloudflare 给 R2 绑定的公开访问域名https://pub-hashcode.r2.dev)去拼接同样的路径,浏览器里是可以正常打开的。

也就是说:图床没挂,是 PicGo 吐出来的 URL 有问题。

排查:到底是哪一层在掉链子

我一步步做了隔离验证:

验证项结果
浏览器直接访问 R2 的 S3 API 域名403,因为 R2 的 r2.cloudflarestorage.com 是私有端点,默认不对外公开访问
浏览器访问公开域名 r2.dev + 同样的路径200,图片正常显示
Typora 里把链接改成 r2.dev 域名依然不渲染
检查 PicGo 自定义域名配置发现只填了 https://pub-xxx.r2.dev,上传后返回的 URL 只有域名,没有后面的文件路径

到这里,问题拆成了两个:

  1. 域名不对:应该用 r2.dev 公开域名,而不是 cloudflarestorage.com 私有端点。
  2. URL 拼接不全:PicGo 只返回了域名根地址,缺少 /2026/07/xxx.png 这一段。

根因:outputURLPattern 的占位符理解错了

PicGo 的 S3 插件文档里明确写了:旧的 urlPrefixurlSuffix 已经废弃,请使用 outputURLPattern

我最初的 outputURLPattern 配置是这样的(错的):

https://pub-hashcode.r2.dev/{md5}.{extName}

同时我的 uploadPath 配置是:

{year}/{month}/{md5}.{extName}

结果上传后 PicGo 返回了:

https://pub-hashcode.r2.dev/2026/07/{md5}.png

{md5} 被原样输出了,没有替换成实际的哈希值。

问题的核心:outputURLPattern 并不支持 {md5} 占位符。

文档里写得清楚,outputURLPattern 支持的变量是这些:

占位符说明
{path}完整路径,等于 {dir}/{uploadedFileName}
{uploadedFileName}上传后的文件名(含扩展名)
{dir}上传目录
{protocol}{host}{port}URL 组成部分

{md5}{year}{month} 这些只在上传路径 uploadPath 里有效。当文件已经被命名为 {md5}.{extName} 并上传到 {year}/{month}/ 目录后,它在输出模板里的身份已经变成了 {uploadedFileName},所在目录变成了 {dir}

所以我在 outputURLPattern 里写 {md5},PicGo 根本不认,直接原样输出了字符串 {md5}

修复:用 {path} 一把梭

正确的 outputURLPattern 应该是:

https://pub-hashcode.r2.dev/{path}

对应的完整配置如下:

配置项
uploadPath{year}/{month}/{md5}.{extName}
endpointhttps://...r2.cloudflarestorage.com
customUrlhttps://pub-hashcode.r2.dev
outputURLPatternhttps://pub-hashcode.r2.dev/{path}

保存后重新上传,PicGo 返回的链接变成了:

https://pub-hashcode.r2.dev/2026/07/xxxxxx.png

Typora 里立刻正常渲染。

下图展示PicGo中的配置页面:

image-20260719190535169

教训

  1. R2 的 S3 API 端点 ≠ 公开访问端点*.r2.cloudflarestorage.com 是给程序调用的,要给访客看图片,必须绑定 *.r2.dev 或使用自定义域名,并在 PicGo 里通过 outputURLPattern 输出正确的公开地址。

  2. uploadPathoutputURLPattern 的占位符是两回事{md5}{year} 只在定义上传目录和文件名时可用;输出 URL 时,文件已经落地,要用 {path}{uploadedFileName}{dir} 来引用。

  3. 裂图不一定是图床挂了。先拿浏览器直接访问图片 URL,确认是权限问题、路径问题,还是 Markdown 语法问题,能少绕很多弯路。

ZB

Zhanbo Chen

Java Backend & AI Agent Developer

Back to home
Comments