1374 字
7 分钟
使用 Cloudflare 创建属于自己的免费图床

在写博客或者做个人项目时,一个稳定且免费的图床必不可少。目前市面上的图床要么限制多,要么面临随时跑路的风险。今天记录一下如何使用 Cloudflare R2 + Pages 搭建一个属于自己的免费图床。

这个方案有几个巨大的优势:

  1. 免流量的费用:Cloudflare R2 的读取操作和流量完全免费。
  2. 国内访问友好:使用 Pages 提供的 pages.dev 域名,相比被墙的 workers.dev 来说,在国内很多时候可以直连,速度尚可。
  3. 防超额扣费:通过 Pages Functions 代理和强缓存,配合 Fail closed 机制,杜绝了超额扣费的风险。
  4. 目录结构自定义:直接映射 R2 中的文件夹结构,无需重新部署即可上传新图。

准备工作#

  • 一个 Cloudflare 账号。
  • 一张银行卡(储蓄卡或信用卡都可以)或 PayPal(开通 R2 需要验证,但不会产生费用)。

第一步:创建并配置 R2 存储桶#

  1. 登录 Cloudflare 控制台,在左侧导航栏找到并进入 R2。
  2. 点击 创建存储桶,并给你的图床起个名字,例如 images,位置选择 自动(亚太地区),默认存储类选择 标准。
  3. 创建完成后,进入该存储桶的 设置 页面。
  4. 默认情况下,存储桶不能公开访问,但还是建议确认一下。 找到 公共开发 URL,确认其为关闭的。我们要保证存储桶是私有的,所有访问必须走我们自己的 Pages。
  5. 在存储桶中点击 创建文件夹 ,然后进去上传图片。比如创建一个 example 文件夹,里面再建一个 album 文件夹,上传一张 01.jpg,它的 Key 就是 example/album/01.jpg。

第二步:创建 Pages 项目并绑定 R2#

  1. 在控制台进入 Workers 和 Pages,创建一个新的 Pages 项目(Pages 项目在底下的小字部分),选择 拖放文件 选项。
  2. 进入 Pages 项目的 设置 -> 绑定。
  3. 点击 添加 -> R2 存储桶:
    • 变量名称 填入 Images(代码里会用到,请保持一致,注意大小写)。
    • R2 存储桶 选择你刚创建的 images。
  4. 保存后,必须重新部署一次项目,绑定才会生效。

第三步:编写 Functions 代码#

我们要让 Pages 在根目录下拦截所有请求,去 R2 里找对应的图片。

由于在 Cloudflare Pages 中,要使 functions 生效,必须要使用 Wrangler 部署。因此,我们在电脑的空白文件夹下创建 functions/[[path]].js 文件,并写入以下代码:

functions/[[path]].js
export async function onRequest(context) {
const { request, env, params } = context;
if (request.method !== "GET" && request.method !== "HEAD") {
return new Response("Method Not Allowed", { status: 405 });
}
// params.path 是路径片段数组,例如 /example/01.jpg → ["example", "01.jpg"]
const rawKey = (params.path || []).join("/");
// 安全清理,防止 ../ 路径遍历
const key = rawKey
.split("/")
.filter((segment) => segment && segment !== "." && segment !== "..")
.join("/");
// 根路径 / 没有对应对象,返回一个简单提示
if (!key) {
return new Response("Image Hosting", { status: 200 });
}
// 这里的 Images 应该和上面 R2 存储桶的变量名称一致
const object = await env.Images.get(key);
if (object === null) {
return new Response("Not Found", { status: 404 });
}
const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set("etag", object.httpEtag);
headers.set("Cache-Control", "public, max-age=31536000, immutable");
if (request.method === "HEAD") {
return new Response(null, { headers });
}
return new Response(object.body, { headers });
}

第四步:使用 Wrangler 部署项目#

  1. 确保你的电脑安装了 Node.js。
  2. 打开终端(命令行),进入你刚刚创建 functions 文件夹的根目录。
  3. 运行以下命令进行部署(第一次运行可能会提示你登录 Cloudflare 账号,按提示授权即可):
Terminal window
npx wrangler pages deploy . --project-name=<你的项目名称>

部署成功后,终端会返回一个预览或生产环境的 URL。

第五步:设置防超额扣费#

这是整个方案中最核心的一步。由于 R2 免费额度用完后是 自动按量计费 的,为了确保万无一失,我们需要利用 Pages Functions 的额度限制来间接锁死 R2 的消耗。

  1. 进入你的 Pages 项目,点击 设置 -> 运行时。

  2. 找到 失败开放 (Fail open) / 失败关闭 (Fail closed) 选项,将其修改为 失败关闭 (Fail closed),然后保存。

为什么选 Fail closed?

Pages Functions 的免费额度是 每天 10 万次请求,当 10 万次额度用尽后,Pages 会直接停止工作(返回 1027 错误),而不会继续绕过 Function 去请求后面的资源。这样一来,你的 R2 读取次数被死死卡在每天 10 万次以内,远远低于 R2 免费提供的每月 1000 万次读取额度,这样就可以有效防止超额扣费。

第六步:测试与验证#

部署完成后,在浏览器中打开你的图片链接:

https://你的项目名称.pages.dev/example/album/01.jpg

如果图片正常显示,说明基本配置已经成功。至此,你的专属免费图床已经搭建完毕。

日常使用指南#

  • 上传新图:直接在 Cloudflare R2 控制台进入对应的文件夹上传即可,无需再次运行 Wrangler 部署,URL 会自动生效。

  • 引用图片:在博客或论坛中,直接使用 https://你的项目名称.pages.dev/文件夹/子文件夹/文件名.jpg 即可。

  • 代码备份:请务必妥善保存本地的 functions/[[path]].js 文件。由于我们使用的是直接上传部署,云端的代码只是编译后的产物,本地代码可以帮助你日后修改配置。

使用 Cloudflare 创建属于自己的免费图床
https://birdjiujiuuu.github.io/posts/20261028/
作者
Birdjiujiuuu
发布于
2026-10-28
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。