MD2WX 图床系统与自动换链指南
基于 R2 搭建零成本图床,支持 Web 与 CLI 上传,推稿时自动换链至微信 CDN。
MD2WX 图床系统与自动换链指南
作者:野生宝藏箱
项目:MD2WX(微信公众号 Markdown 排版转换器与草稿箱直推工具)
核心主题:图床系统演进、Cloudflare R2 零成本搭建与微信 CDN 自动换链

00. 痛点:为什么写公众号时,配图总在折磨创作者?
在微信公众号写作流程中,文章正文的排版转换往往只需要几秒钟,但配图处理却经常让创作者陷入繁琐的机械操作。
主要痛点集中在三个方面:
1. 外部图片防盗链拦截(破图红叉)
在本地写技术长文或产品笔记时,经常需要引用 GitHub 仓库截图、技术文档图表或外部博客配图。当你将渲染好的富文本直接粘贴到微信公众平台编辑器时,微信后台会严格校验图片来源的 HTTP Referer。绝大多数外部图床或平台都会触发防盗链拦截,文章群发后读者端直接显示为红叉,或显示文字提示:“此图片来自未授权平台,不可引用”。
2. 本地图片无法直接复制进微信后台
本地 Markdown 文件中,插图通常采用相对路径写法,例如 。在本地 VS Code 或 Obsidian 里预览没有任何问题,但由于浏览器安全沙箱限制,微信网页版编辑器根本无法读取你本地硬盘上的绝对或相对路径。
以往很多人的妥协做法是:打开微信后台编辑器,点击“上传图片”,从文件管理器中一张张找出对应的配图上传,再人工替换掉正文中的占位符。一篇包含十几张插图的技术文章,仅这一项机械操作就要耗费 20 到 30 分钟。
3. 传统图床工具的配置负担与凭据安全风险
市面上的图床客户端工具(如 PicGo 等)固然强大,但在面向 Web 静态工作台或团队协作时存在天然矛盾:
- 如果要在纯前端(如 GitHub Pages 托管的 Web Studio)实现上传,通常需要将云厂商对象存储(AWS S3、腾讯云 COS、阿里云 OSS)的
AccessKey和SecretKey填写在前端配置中,这极易导致主凭据泄露; - 商业对象存储往往有固定的存储费用与下行流量计费,稍有不慎遭遇恶意盗刷,容易产生意料之外的账单;
- 对很多仅仅想写写文章的个人创作者来说,配置一整套存储桶权限、CORS 规则和鉴权算法门槛过高。
针对上述问题,MD2WX 在最近的更新中提供了一套完整的图片处理闭环方案。

01. MD2WX 的三层图片架构
为了彻底解决图片破图与本地上传难题,MD2WX 从底至上设计了三层互为补充的图片处理链路:
[本地 Markdown 编写]
│
├── 1. Web Studio / CLI 手动上传
│ └──> Cloudflare Worker 代理 (/api/public/uploads 或 /api/uploads)
│ └──> 写入 Cloudflare R2 存储桶 (10GB 免费,无出流量费)
│ └──> 获得公网稳定外链,插入 Markdown
│
└── 2. 执行 CLI 一键推稿 (md2wx article.md --publish)
└──> 解析正文中的全部图片 (本地路径 / 外部 URL / R2 链接)
└──> 调用微信官方 media/uploadimg 接口
└──> 全自动上传并重写为微信官方 CDN (mmbiz.qpic.cn) 永久链接
第一层:微信官方 CDN 自动换链(零配置兜底)
这是 MD2WX 最省心的特性,不需要用户配置任何第三方图床。
当你在命令行执行 md2wx article.md --publish 时,内置的 uploader.py 会在提交草稿箱之前自动执行以下动作:
- 扫描 AST 中所有的
<img>标签与 Markdown 图片语法; - 识别本地相对路径文件(如
./images/demo.png)或外部公网 URL; - 将图片二进制数据读取或下载至内存,计算 MD5 指纹(在本地
~/.config/md2wx/下建立映射缓存,避免重复上传相同图片); - 调用微信公众平台官方的
media/uploadimg接口,将图片上传至微信官方素材 CDN; - 将正文中所有的原图片链接,逐一就地重写为微信官方的
https://mmbiz.qpic.cn/...永久链接。
这意味着,你在本地写稿时可以随意使用相对路径,推送到微信后台后,正文里的图片已全部变成了合规且永久免防盗链的微信官方 CDN 地址。
第二层:统一契约的通用图床客户端
如果创作者希望在写作阶段就生成可供公网访问的图片链接(例如在 Web Studio 中实时预览,或将文章同步到其他博客平台),MD2WX 在 CLI 和 Web 端内置了通用的图床客户端(imagehost.py 与 imagehost.js):
- 采用通用
multipart/form-data标准接口契约; - 表单字段名(默认
file)、鉴权头(默认Authorization)、令牌前缀及返回 JSON 提取路径均支持灵活配置; - 不仅支持对接自建服务,也能无缝接入各种兼容标准表单上传的图床服务。
第三层:Cloudflare Worker + R2 官方开源模板(零成本持久化)
为了给不想购买昂贵商业存储的用户提供开箱即用的方案,MD2WX 在仓库中直接开源了一个轻量级代理服务模板(位于 cloudflare/r2-imagehost/,代码量仅约 150 行)。
为什么选用 Cloudflare R2?
- 免费额度充足:每个 Cloudflare 账户享有每月 10GB 的免费存储额度,数百万次标准读写操作;
- 完全免收出流量费(Zero Egress Fee):与 AWS S3 等产品不同,Cloudflare R2 不对数据传出计费,彻底消除被盗刷流量导致巨额账单的后顾之忧;
- 全球边缘 CDN 加速:依托 Cloudflare 全球 Anycast 网络,图片访问速度极快。

02. 两分钟搭建你的专属 R2 图床
如果你还没有个人图床,可以按照以下步骤使用 MD2WX 提供的模板部署一个。
准备条件
- 具备 Node.js 环境;
- 一个已注册的 Cloudflare 免费账户。
部署步骤
进入仓库的 cloudflare/r2-imagehost 目录:
cd cloudflare/r2-imagehost
# 1. 登录 Cloudflare(会唤起浏览器授权)
npx wrangler login
# 2. 创建一个 R2 存储桶(名称需与 wrangler.toml 中的 bucket_name 一致)
npx wrangler r2 bucket create md2wx-images
# 3. 设置私密上传令牌(用于保护 CLI 接口,输入一段随机安全密钥即可)
npx wrangler secret put UPLOAD_TOKEN
# 4. 执行一键部署
npx wrangler deploy
部署完成后,终端会打印出分配给你的 Worker 地址:
https://md2wx-imagehost.<你的子域>.workers.dev
接口路由说明
| 请求方法 | 路径 | 鉴权方式 | 适用场景 |
|---|---|---|---|
POST | /api/uploads | 需携带 Authorization: Bearer <TOKEN> | CLI 本地调用或私有脚本 |
POST | /api/public/uploads | 免密,受 Origin 白名单与 IP 速率限制保护 | Web 静态站(不泄露主凭据) |
GET | /images/<key> | 公开访问,内置 Cache-Control: immutable | 图片高速分发取图 |
GET | /health | 公开访问 | 服务探活与连通性检查 |
你可以通过一条简单的 curl 命令验证图床是否正常运作:
curl -X POST https://md2wx-imagehost.<你的子域>.workers.dev/api/uploads \
-H "Authorization: Bearer <你设定的UPLOAD_TOKEN>" \
-F "file=@/path/to/test.png"
如果返回如下 JSON,即说明部署成功:
{
"url": "https://md2wx-imagehost.<你的子域>.workers.dev/images/2026/09/24/xxxxxxxx.png"
}
03. 双端接入与使用工作流
图床服务部署就绪后,接入 MD2WX 仅需几行配置。
1. CLI 命令行接入
在项目根目录的 .env 文件(或系统环境变量)中填入:
# 图床接口地址
IMAGE_HOST_UPLOAD_URL=https://md2wx-imagehost.<你的子域>.workers.dev/api/uploads
# 鉴权令牌与前缀
IMAGE_HOST_TOKEN=your_secret_upload_token
IMAGE_HOST_AUTH_PREFIX=Bearer
工作流 A:单图快速上传
在终端里遇到需要外链的图片,直接使用 --upload-image 命令:
md2wx --upload-image ./screenshots/demo.png
终端会秒级上传并输出标准 Markdown 图片语法:
[+] 图片上传成功!
原始路径: ./screenshots/demo.png
外链地址: https://md2wx-imagehost.<你的子域>.workers.dev/images/2026/09/24/a1b2c3d4.png
Markdown: 
工作流 B:一键发布全自动重写
写完文章后,执行发布命令:
md2wx article.md --publish
无论正文里使用的是本地相对路径(如 assets/diagram.png)还是 R2 图床地址,发布引擎都会在向微信草稿箱推送前,自动完成微信 CDN 转存换链,确保微信后台素材库与正文引用完全一致。
2. Web Studio 网页端使用
对于通过浏览器使用 md2wx.zaneven.com 的用户:
- 直接上传与插入:在编辑区域上方工具栏中,点击“插入图片”下拉菜单中的“上传图片”,选择本地文件即可完成上传,光标处会自动插入上传后的 Markdown 链接;
- 免密安全防护:静态网页端请求的是
/api/public/uploads接口,前端代码中没有任何私密密钥,仅通过 Origin 白名单校验来源; - 未配置环境的主动提示:如果前端未检测到有效的图床环境变量,点击上传时会弹出温和的指引提示,避免用户误操作。

04. 架构中的安全防刷与可靠性细节
作为一项面向生产环境的基础功能,MD2WX 在图床设计上兼顾了安全与防护:
1. 严格的凭据隔离
- R2 的 S3 AccessKey 与 SecretKey 仅存在于 Cloudflare Worker 内部,浏览器前端和普通客户端完全接触不到对象存储的主控制凭据;
- CLI 端使用独立的
UPLOAD_TOKEN进行鉴权; - Web 端采用来源白名单限制(
ALLOWED_ORIGINS),杜绝接口被其它第三方站点肆意调用。
2. Workers Rate Limiting 边缘限流
针对公开路由 /api/public/uploads,模板在 wrangler.toml 中预置了 Cloudflare Workers 原生 Rate Limiting 绑定:
- 限制单个客户端 IP 每 60 秒最多请求 60 次;
- 正常的文章编写上传(单篇通常几张到几十张)完全不受限制,而恶意的脚本刷量则会在边缘节点直接被拦截并返回
HTTP 429 Too Many Requests,避免存储桶被异常塞满。
3. 本地 MD5 缓存去重
在向微信草稿箱同步图片时,uploader.py 会基于文件内容的 MD5 值在本地维护一份转换索引。如果同一篇文章多次预览或更新草稿,已上传过的图片会直接命中缓存,无需重复消耗网络带宽与微信素材库配额。
05. 总结
优质的内容输出应当专注于构思与文字本身,而不应被破图、防盗链拦截以及人工复制上传所消耗。
通过微信官方 CDN 自动重写、通用图床客户端与基于 Cloudflare R2 的零成本部署模板,MD2WX 将公众号长文的配图流转环节压缩到了近乎无感的状态。
如果你经常受制于微信排版中的配图痛点,不妨拉取最新版本体验。
项目开源主页:https://github.com/zaneven/MD2WX
在线工作台:https://md2wx.zaneven.com
图床 Worker 模板:cloudflare/r2-imagehost