1699 字
8 分钟
使用 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),然后保存。

第六步:测试与验证#

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

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

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

(可选)设置自定义域名#

如果你希望图床链接使用自己的域名,可以在这一步继续配置,整个配置过程完全 不影响你已有的主域名或其他子域名解析。

  1. 在 Cloudflare Pages 中添加域名
  • 在 Cloudflare 中选择你的图床项目,点击 自定义域 -> 设置自定义域,输入你想要的子域名(如 imgs.你的域名.com)并继续。

  • 页面会给出一个 CNAME 目标地址(通常是你的 项目名.pages.dev),请记录下来。

  1. 在域名服务商处配置解析
  • 登录你的域名后台,进入 Advanced DNS 选项。

  • 添加一条新的 CNAME Record 并保存:

HostValueTTL
imgs(你的子域名前缀)刚才记录下的 CNAME 目标地址自动 (Automatic)
  1. 等待生效 DNS 通常需要几分钟到半小时生效。回到 Cloudflare Pages 的页面,当状态变为 “活动” (Active) 时,说明配置成功,SSL 证书也会自动签发。

配置完成后,你原有的 pages.dev 地址依然可以访问。但在博客中引用图片时,你可以使用你自己的专属链接了,例如将 https://你的项目名称.pages.dev/example/album/01.jpg 替换为 https://imgs.你的域名.com/example/album/01.jpg。

日常使用指南#

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

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

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

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

分享文章

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

继续阅读

沿着主题读

基于共同的标签与分类