567 字
2 分钟
利用 cloudflare 搭建个人图床
2026-04-06

为什么用cloudflare#

优点:

  • 每月 10GB 存储 + 1000万次读取,根本用不完。
  • 零流量费用,一定程度上能防止被刷流量。

缺点:

  • 速度不及国内服务商。
  • 要绑定信用卡,可能不太安全。。

获取部分#

1. 创建 cloudflare r2 存储桶#

直接创建就好了,名字顺便填,下面记为 r2-name ,地区选择亚太地区。

然后就可以拖动上传一张照片试试了。

2. 创建 worker 处理#

直接创建 worker,选择从 hello world 开始,名字顺便。

点编辑代码,全选替换为:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const referer = request.headers.get('Referer');
    const allowedDomains = [// 允许访问的域名列表
      'baidu.com' //要改
    ];
    let isAllowed = !referer;// 检查 Referer 是否在允许列表中
    if (referer) {// 检查 Referer 是否包含允许的域名
      for (const domain of allowedDomains) {
        if (referer.includes(domain)) {
          isAllowed = true;
          break;
        }
      }
    }
    if (!isAllowed) { // 如果不允许访问(直接访问或其他网站引用)
      // 返回防盗链提示图,建议直接返回文字,不然会占请求 B 类的次数
      // const warningImage = await env.MY_BUCKET.get('hotlink-warning.webp');
      // if (warningImage) {
      //   const headers = new Headers();
      //   headers.set('Content-Type', 'image/jpeg'); // 如果是 PNG 改为 image/png
      //   headers.set('Cache-Control', 'public, max-age=3600'); // 缓存1小时
      //   headers.set('X-Robots-Tag', 'noindex');
      //   return new Response(warningImage.body, {
      //     status: 200,
      //     headers
      //   });
      // }
      // 如果提示图不存在,返回文字提示
      return new Response('Hotlinking is not allowed.', {
        status: 403,
        headers: {
          'Content-Type': 'text/plain',
          'X-Robots-Tag': 'noindex'
        }
      });
    }
    const userAgent = request.headers.get('User-Agent') || '';
const blockedUA = ['curl', 'python-requests', 'Go-http-client', 'java'];
if (blockedUA.some(bad => userAgent.toLowerCase().includes(bad))) {
return new Response('Forbidden: Bot not allowed', { status: 403 });
}
    // 从 R2 获取文件
    const objectKey = url.pathname.slice(1); // 去掉开头的 /
    // 如果路径为空,返回提示
    if (!objectKey) {
      return new Response('R2 Image CDN - Please specify image path', {
        status: 400,
        headers: { 'Content-Type': 'text/plain' }
      });
    }
    // 从 R2 获取对象
    const object = await env.MY_BUCKET.get(objectKey);
    if (object === null) {
      return new Response('Image Not Found', {
        status: 404,
        headers: { 'Content-Type': 'text/plain' }
      });
    }
    // 设置响应头
    const headers = new Headers();
    object.writeHttpMetadata(headers);
    headers.set('etag', object.httpEtag);
    // 设置缓存
    headers.set('Cache-Control', 'public, max-age=5184000, immutable');
    // 设置 CORS(允许跨域)
    //headers.set('Access-Control-Allow-Origin', '*'); //
    // 返回图片
    return new Response(object.body, {
      headers
    });
  }
}

点保存修改,再点右上角的部署。

3. 链接 r2#

到 worker - 绑定 - R2 存储桶(如果没有按 CTRL+F5 刷新一下

变量名称填 MY_BUCKET ,R2 存储桶选你创建的那个 r2-name ,点部署。

4. 设置域名#

点设置 - 域和路由 - 添加。

输入你的域名就可以了。

5. 测测#

假如你的存储库中有 123.webp 的一张图片,在浏览器输入 <你的域名>/123.webp ,若出现 Hotlinking is not allowed. 就成功了。

上传部分#

r2 token#

R2 - 创建 Account API 令牌

名称顺便,权限是对象读和写,指定你创建的那个桶,时间永久。然后点创建。

一定要保存好令牌值,访问密钥 ID,Endpoint 和机密访问密钥!!!

一定要保存好令牌值,访问密钥 ID,Endpoint 和机密访问密钥!!!

一定要保存好令牌值,访问密钥 ID,Endpoint 和机密访问密钥!!!

只显示一次。或者建议不要关掉这个页面。

PicList#

这里使用的是 PicList ,下载不说。

350

打开 图床 - AWS S3。

前面的把获取的那些东西填进去就好了。

  • region 填 auto
  • 设置自定义节点:你的账号ID.r2.cloudflarestorage.com(无 https)
  • 设置自定义域名:https://你的域名(有 https)

点确定,设为默认

然后就行了。

注意防盗链可能会防住自己。。就是在本地编辑时看不了。,,,所以我就把防盗链改成无 referer 也可以。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

部分信息可能已经过时