[ 跳转到主要内容 · Skip to Content ]
文稿 / 技术折腾 / 告别图床刺客:基于 CloudFlare-ImgBed 与 R2 构建高可用边缘图床及自动化管线

告别图床刺客:基于 CloudFlare-ImgBed 与 R2 构建高可用边缘图床及自动化管线

从零搭建 img.halfair.top 无服务器图床,打通本地 sharp 转码、SHA-256 指纹去重与 Markdown 自动回写闭环

HalfAir · 文摘卡片 2026-11-06 · 技术折腾
“不要温和地走进那个良夜。”
写独立博客最怕两件事:一是免费公共图床突然跑路导致旧文满屏裂图,二是国内对象存储遭遇恶意刷量产生天价流量账单。本文系统拆解如何基于开源项目 CloudFlare-ImgBed 与 R2 零出站流量费存储桶搭建生产级边缘图床,并公开本站正在使用的自动化压缩上传管线。

一、 序言:写博客最怕的不是没灵感,而是数年后满屏的裂图

维护独立博客超过一年的人,几乎都经历过被“图床”背刺的时刻。

最早写软路由折腾笔记时,为了图省事,我曾把截图随手拖进过几个号称“永久免费”的公共图床。结果不到半年,其中一家因为域名未续费直接蒸发,另一家则突然加上了严苛的跨域拦截—⁠—某天深夜我点开自己半年前写的教程,发现原本夹在文字中间的十几张关键配置截图全变成了灰色的碎裂图标。一篇没有配图的硬件实操手记,读起来就像一份被撕掉图纸的说明书。

后来我也试过两个常见的替代方案,但各自都有绕不开的硬伤:

• 把原图直接塞进 Git 静态仓库:写文章时确实顺手,但手机拍的照片或高分屏截出来的 PNG 动辄三四兆。十几篇文章写下来,.git 目录膨胀到好几百兆,每次 git push 或 CI 构建都要拉取半天,国内访客打开页面更是像在挤牙膏。

• 使用国内传统云厂商的 OSS / COS 对象存储:速度确实快,但它的计费模型里藏着一把悬在头顶的剑—⁠—按量计费的公网出站流量费与 CDN 回源费。个人博客根本招架不住恶意爬虫或盗链脚本的半夜刷量,一觉醒来欠费几百块的案例在社区里比比皆是;而如果为了自保开启极严的空 Referer 拦截,又会导致所有通过 RSS 阅读器看文章的读者看到满屏裂图。

为了彻底终结这种焦虑,在重构本站(HalfAirの博客)时,我基于开源项目 MarSeventh/CloudFlare-ImgBed 配合 Cloudflare R2 对象存储,搭起了本站专属的边缘图床网关(https://img.halfair.top),并在本地写了一套自动压缩、哈希去重与链接回写脚本。现在你在这座博客里看到的每一张文章配图、外设线框图乃至角落里的微贴纸,全部跑在这套零月租的边缘架构上。

二、 架构拆解与模式选型:Pages 还是 Worker?Telegram 还是 R2?

在动手配置之前,有必要先把 CloudFlare-ImgBed 进化到 v2.x 之后的双层架构理清楚。它把“元数据索引”与“二进制文件实体”做了干净的剥离:所有的文件列表、目录树(如 blog/、gear/)、访问黑白名单都存在 Cloudflare KV(img_url) 中;而真正的图片字节流,则支持路由到多种后端存储渠道(uploadChannel)。

在计算载体上,官方提供了 Pages 部署与 Worker 部署两种模式:

1. Cloudflare Pages 模式:需要 Fork 源码仓库并连接 Pages 自动构建。优点是方便自己二次修改前端界面,缺点是每次更新版本都要跑一遍完整的前端编译流程。

2. Cloudflare Worker 模式(推荐生产使用):直接下载官方编译好的单文件 worker.js 部署在 Workers 上(详见官方 Worker 部署文档)。它省去了冗长的构建步骤,冷启动极快,绑定 KV 和 R2 也更加直观。

而在后端存储渠道的选择上,强烈建议参考下表根据自己的场景做取舍:

TABLE 01 // CloudFlare-ImgBed 主流存储后端渠道工程对比与选型建议
存储渠道 (`uploadChannel`)底层存储介质容量与免费额度核心优势潜在短板与适用定位
Cloudflare R2 (cfr2) Cloudflare 原生对象存储 10 GB 免费容量 + 零出站流量费 内网直连速度最快、不受第三方接口风控影响、支持超大单文件 超出 10GB 后按 $0.015/GB/月 计费;最适合作为博客主力生产图床
Telegram (telegram) Telegram 私有频道附件 理论无限容量(单文件受 Bot API 限制 ≤ 20MB) 完全免费、不占任何云盘额度、自带异地聊天记录备份 偶发受 TG 接口限流影响,跨网拉取首字节略慢于 R2;适合作为冷备或大体积杂项图床
外部 S3 (s3) 兼容 S3 协议的对象存储(B2 / 缤纷云 / MinIO) 视具体服务商而定 可直接挂载已有的自建 NAS MinIO 或第三方存储桶 需跨网走公网 S3 签名请求,延迟取决于源站物理位置

三、 生产级部署全流程:从 R2 桶绑定到边缘缓存加固

下面以我部署 https://img.halfair.top 所采用的 Worker + R2 主存储 + KV 索引 方案为例,完整梳理一遍从零落地的四个标准步骤。

第一步:创建 KV 索引库与 R2 存储桶

登录 Cloudflare 控制台,先准备好两个底层存储容器:

1. 进入 存储和数据库 -> KV,点击创建命名空间,名称填写 img_url(用于存放全站图片索引、文件夹结构与后台设置)。

2. 进入 R2 对象存储 -> 概述,点击创建存储桶(Bucket),名称填写 halfair-imgbed(位置选择自动即可)。

第二步:创建 Worker 并挂载硬件绑定

进入 计算 (Workers & Pages) -> 创建 Worker,取名 cloudflare-imgbed。前往 MarSeventh/CloudFlare-ImgBed Releases 下载最新版的 worker.js,将代码粘贴进 Worker 在线编辑器(或使用 Wrangler CLI 推送)并保存。

随后进入该 Worker 的 设置 (Settings) -> 绑定 (Bindings),挂载刚刚创建的两个容器(注意:变量名必须严格与下列名称一致,否则程序无法识别):

• 添加 KV 命名空间绑定:变量名称填 img_url,选择刚才创建的 img_url 命名空间。

• 添加 R2 存储桶绑定:变量名称填 img_r2,选择刚才创建的 halfair-imgbed 存储桶。

第三步:配置后台鉴权与多渠道参数

在 Worker 的 设置 -> 变量和机密 (Variables and Secrets) 中,或是部署后首次访问后台的图形化设置页(/admin)里,配置核心安全锁:

第四步:绑定自定义域名与配置边缘强缓存(性能关键)

在 Worker 的「触发器 / 自定义域」里添加你自己的二级域名(例如 img.halfair.top)。域名生效后,强烈建议去 Cloudflare 域名控制台的 Caching (缓存) -> Cache Rules (缓存规则) 新增一条专门针对图床静态路径的强缓存规则:

• 匹配条件:主机名 等于 img.halfair.top 且 URI 路径 开头为 /file/

• 缓存操作:选择 符合缓存条件 (Eligible for cache),将 边缘 TTL (Edge TTL) 设为 1 个月,浏览器 TTL (Browser TTL) 设为 1 年。

为什么这一步如此重要?因为默认情况下,Worker 动态返回的流可能不会在边缘节点长久驻留。加上这条缓存规则后,任何一张图片只要被第一个读者加载过一次,就会直接缓存在离读者最近的 Cloudflare 边缘机房里—⁠—后续成千上万次访问不仅能做到 15ms 内秒开,而且完全不再消耗你的 Worker 每日请求配额和 R2 读取次数!

配置 BASIC_USER(后台管理员账号)与 BASIC_PASS(后台管理密码),防止陌生人闯入你的图床管理面板删图;同时在后台「安全设置 -> API Token 管理」中生成一枚专供上传脚本使用的 IMGBED_TOKEN(勾选允许上传与指定目录权限),关闭匿名游客随意上传通道。

wrangler.toml (若使用 Wrangler CLI 自动化部署的标准绑定配置)
toml
name = "cloudflare-imgbed"
main = "worker.js"
compatibility_date = "2026-03-01"
[[kv_namespaces]]
binding = "img_url"
id = "在此填入你的_KV_NAMESPACE_ID"
[[r2_buckets]]
binding = "img_r2"
bucket_name = "halfair-imgbed"

四、 终极生产力闭环:API 鉴权上传与博客自动化去重管线

图床搭好之后,如果每次写文章还要手动打开网页后台、把截图拖进去、复制链接再切回编辑器粘贴,写一篇二十张图的文章还是太折腾了。

好在 CloudFlare-ImgBed 提供了极其规整的 /upload RESTful 接口。为了把写文章的摩擦降到零,我在本博客的工程仓库里直接内置了一套自动化资产治理脚本(scripts/upload-images.js)。平时我在本地写 Markdown 时,只需要把相机照片或截图丢进本地目录,跑一行 npm run images:upload,脚本就会在几秒钟内自动完成四件事:

1. 智能转码与尺寸收敛:调用 sharp 高性能图像引擎,将宽度超过 1440px 的超清原图等比缩放,并以 quality: 82 编码为现代 WebP 格式—⁠—实测一张 4.2 MB 的相机实拍图,转码后仅剩 95 KB 左右,体积削减超过 97%,肉眼几乎看不出画质损失。

2. SHA-256 + MD5 双重指纹去重:上传前先计算二进制内容的 SHA-256 与 MD5 哈希值,比对仓库根目录的 asset-manifest.json 账本。如果发现这张图以前已经传过了,直接秒级复用已有的 https://img.halfair.top/file/blog/... 链接,100% 杜绝重复上传产生垃圾文件。

3. 自动调用 /upload 接口上云:对真正新增的图片,携带 .env 中的 IMGBED_TOKEN 发送 FormData 请求至 cfr2 渠道,自动归档到云端的 blog/ 文件夹下。

4. 源码无感原地回写:拿到图床返回的永久 CDN 链接后,自动扫描并替换 .md 文稿中的本地路径,全程无需手动复制粘贴一次 URL。

cURL 命令行单图快传与 PicGo 客户端配置速查

CLI

如果你习惯在终端用命令行临时传一张图,或者配合 Typora + PicGo 使用,只需向 https://你的图床域名/upload?uploadChannel=cfr2&returnFormat=full&uploadFolder=blog 发送带 Authorization: Bearer <Token> 请求头的 multipart/form-data POST 请求(字段名为 file)。在 cURL 中一行即可搞定:curl -X POST "https://img.halfair.top/upload?uploadChannel=cfr2&returnFormat=full" -H "Authorization: Bearer $IMGBED_TOKEN" -F "file=@./screenshot.webp"。

scripts/upload-images.js (CloudFlare-ImgBed API 上传与哈希去重核心实现)
javascript
async function uploadBufferToImgBed(buffer, filename, mimeType, config) {
const endpoint = new URL(`${config.baseUrl}/upload`);
endpoint.searchParams.set('uploadChannel', 'cfr2'); // 指定写入 Cloudflare R2 存储桶
endpoint.searchParams.set('returnFormat', 'full'); // 返回完整 https://img.halfair.top/... 链接
endpoint.searchParams.set('uploadFolder', 'blog'); // 自动按目录归档管理
endpoint.searchParams.set('autoRetry', 'true');
const form = new FormData();
form.append('file', new Blob([buffer], { type: mimeType }), filename);
const res = await fetch(endpoint, {
method: 'POST',
headers: { Authorization: `Bearer ${config.token}` }, // 从本地 .env 安全注入 IMGBED_TOKEN
body: form,
signal: AbortSignal.timeout(25000),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const payload = await res.json();
const item = Array.isArray(payload) ? payload[0] : payload;
return item.src;
}

五、 结语:把数字资产的主权握在自己手里

折腾独立博客这么久,我越来越相信一个朴素的道理:凡是打算留存五年、十年以上的内容,它的底层寻址权就绝不能寄托在别人的免费施舍上。

借助 MarSeventh/CloudFlare-ImgBed 与 Cloudflare R2,我们不需要编写复杂的后端鉴权代码,也不需要为每月的服务器带宽掏一分钱,就能拥有一座完全受自己域名(img.halfair.top)统辖的现代图床。即便未来某天你想迁移到别的存储平台,因为域名解析权牢牢攥在你自己手里,只需把 R2 桶里的文件同步过去、改一下路由指向,全站成百上千篇文章里的图片链接依然一个字都不用改。

这大概就是自建边缘基建最让人踏实的地方。

文字是博客的骨架,而配图是现场的证物。把证物锁进自己掌管密钥的边缘存储桶里,五年后再翻开旧文,每一张截图才依然清晰如初。
— HalfAir 基建手记
参考资料与延伸阅读 · References 共 4 篇
  1. [01]

    开源无服务器图床核心仓库,支持 R2、Telegram、S3 等多渠道存储与目录级管理

  2. [02]

    官方 Worker 单文件部署、KV/R2 绑定与 /upload 接口规范说明

  3. [03]

    社区实战教程:涵盖前置准备、环境变量与防盗链设置细节

  4. [04]

    社区实战教程:多存储渠道对比与客户端上传工具对接经验

读后表态 · Reactions 读完觉得怎么样?顺手点张贴纸留个脚印吧

评论与留言

STANDBY...
SELF-HEALING v2
正在准备评论区运行环境...

全局全文搜索与快捷命令面板

快捷指令 PAGEFIND · STANDBY
检索结果 19 ENTRIES