Cloudflare R2+Workers!马上搭建自己的云上图床!

结果图#

QmVgqgoC7G8NLS21WvR8j9gf5amu33XvuV68ZrgM5B9iFf.webp

原理#

图源由 Cloudflare R2 托管,通过两个 Workers 连接 R2 以展示随机横屏/竖屏图片,静态页面引用 Workers 的 URL 以实现以上界面

创建 Cloudflare R2 存储桶#

R2 实际上是一个对象存储。Cloudflare 提供 10G 的免费存储和每月 1000 万次的免费访问

  1. 进入Cloudflare 仪表盘,进入 R2 页面,如图

    QmU7u2JHUcevyHnwsCdAZfs7X7Fcdh3KJhn6eoy24Q5dGC.webp

  2. 选择创建存储桶QmX3eCaCVEgE8AN29D9t2VpQ5t5SrZGKb8EcZv9oKpCqf2.webp
  3. 为你的存储桶起一个名字,然后单击创建QmVad5eoJCLpSNZ4HCvTPJfD8rpg4aePMzZ7j2DZATn1XD.webp
  4. 进入如下页面就已经创建完毕了QmSdzwBJpw2L4a8LJ3eM3VMJs3d5oV5iFCxCMtv69VZmYH.webp
  5. 返回 R2 首页。因为在下文我们需要使用 API 来进行文件传输,所以需要创建你的 R2 API 令牌,单击管理 R2 API 令牌QmbS8zjJTESwsmycKBSC9kmabAA9dtSCUX8nbUDWg4BWRX.webp
  6. 单击创建 API 令牌,如图QmPzJEHVAm4z3S1SHY4k99TugrPyTB9DXpyRR8Loj22bz3.webp
  7. 因为我们需要该 API 来管理单个 R2 存储桶,所以选择对象读和写,详细配置如图QmNY9p8hksi18B9R8TVfdGgu336oQ3cPmghyfYXE9CDGD4.webp
  8. 创建 API 令牌后,新页面会展示令牌的详细信息,仅会展示一次!!! 保持这个页面,直到你将该页面的所有信息都已经妥善保存,不要关闭界面,否则,你需要轮转 API 令牌以禁用之前的旧密钥,如图QmZTUwbycqbJhVP6PatD3psYy7ej9PDDoiXbmDWoakPhwx.webp
  9. 确保你已经妥善保存你的 R2 API 令牌,然后进行下一步

为你的存储桶添加文件#

因为 Web 界面传输文件较慢且不支持传输大于 300MB 的文件。这里使用本地部署 AList 然后连接你的 R2 存储桶实现高速上传

  1. 笔者使用 Windows。前往AList – Github Release下载适用于 Windows 的最新可执行文件,如图QmPDRDJGeGStreyZMXVYofbE9FCs1T1MyDek3KUbB3Kk5b.webp
  2. 将下载的压缩包解压,并将其中的alist.exe放入一个空文件夹
  3. 单击搜索框,输入 cmd 并回车,如图
  4. QmSt8aFtaeEprJHASEiNPB67UHcHoSxsbhhHUPxW6QkWSo.webp

    QmNkMhDhpPLkYCpVhE1ov7Q6A34uWDvraCqNvuTqaCkujT.webp

    在 cmd 中输入alist.exe server并且不要关闭窗口,运行成功后如图QmdzyY8xbic8jdnZEXegefoZPeizqHa4ZkdMnRKoguBMkf.webp

  5. 打开浏览器,输入localhost:5244即可进入 AList 控制台,如图QmUBFKu7mCiRneCrsTNPxTH6S4gxwtXf9cwLzf4dKW9LLR.webp
  6. 用户名:admin密码:在cmd窗口中,如图。你可以使用鼠标左键在终端中框选内容然后单击鼠标右键进行复制操作QmVH3qZYo3QE6anNHymwkikq5MSeJphrZNR7RCH5jpP3wn.webp
  7. 注意,在 cmd 中,鼠标左键点击或拖动 cmd 的终端界面会导致进入选择状态,程序将会被系统阻塞,需要在终端界面点按鼠标右键解除。若进程被阻塞,cmd 的进程名会多一个选择,请注意。如图是程序被阻塞的例子,在终端界面点按鼠标右键即可解除QmapESiqSEvbYq3AJs15yYvhemRxSHrJaccjTFr99muX6Z.webp
  8. 现在,你已经成功以管理员身份登入了 AList单击最下面的管理QmfNE53GThdjVrh4q64MJcZqwcGPD7UtcYTNw9bVBaSEaF.webp
  9. 你会进入到如图界面。尽管 AList 运行在本地,也建议更改你的用户名和密码QmNdD8UU8fkVDBz5dXdJhCF2fZg8P1FwrcMaaTsG6a7ENy.webp
  10. 更改账密,重新以新账密登录Qmas7pMiPR2FNTXheBT1xGNUpzDiSzv7J7yd6oCuT17yad.webp
  11. 进入控制台,然后单击存储,如图QmS4gGyCM1j3RXgHEPuZ1zTbLAvGtVBEiPXJe9QMF3dD2D.webp
  12. 选择添加,如图QmRDVxt8WbrVkHavgFNXj3qC86ysw6sSZhPy3Uf2ixKp2E.webp
  13. 详细配置如图。挂载路径即 AList 展示路径,推荐使用/R2/你的存储桶名字,地区为autoCloudflare R2+Workers!马上搭建自己的云上图床!回到主页,如图QmSnR9Ptrssx4nqk9qCvhFUNKQyQqJiN7GRscwoj4Dczgj.webp
  14. 尝试上传文件,如图QmPqFsmZNNnh4jNyLS7X3h8Zr6ZCVqTqGVwTxmPDdbmrGW.webp
  15. 可以看到,速度非常快QmXfGK6aZjz741GrY8RfFfKMkUzDMB3xhx93PGZ9S1QycT.webp
  16. 为你的图床创建目录以分类横屏和竖屏图等,以便下文使用 Workers 连接 R2 来调用。后文我将使用R2的/ri/h 路径作为横屏随机图目录、/ri/v 路径作为竖屏随机图目录

QmNdD8UU8fkVDBz5dXdJhCF2fZg8P1FwrcMaaTsG6a7ENy.webp

创建 Workers,连接 R2#

  1. 进入Cloudflare 仪表盘,进入 Workers 和 Pages 页面,如图QmW5UaUap8T2R37u5dzmKGLmUgk4qKnSMFwHBVHqvVbkVA.webp
  2. 单击创建,选择创建 Workers,名称自取,单击部署QmVvLv5n41QQfDfYiVWYRpsfw7TVNGy1BYuv5e8vBRhKLA.webp
  3. 选择编辑代码QmTbRifzXQ593DGyjFQMbA9exyNp2iAeAg4zbVrfFimQc4.webp
  4. 粘贴代码(创建随机横屏图):

新代码:

export default {
async fetch(request, env, ctx) {
const bucket = env.MY_BUCKET;
const url = new URL(request.url);
const hostname = url.hostname;

// 初始化prefix
let prefix = '';

// 根据域名判断prefix
if (hostname === 'hrandom-pic.onani.cn' || hostname === 'api-hrandom-pic.onani.cn') {
prefix = 'ri/h/';
} else if (hostname === 'vrandom-pic.onani.cn' || hostname === 'api-vrandom-pic.onani.cn') {
prefix = 'ri/v/';
} else {
return new Response('Invalid domain', { status: 400 });
}

try {
// 如果是API域名,只返回数量
if (hostname.startsWith('api-')) {
const objects = await bucket.list({ prefix: prefix });
const count = objects.objects.length;
const headers = new Headers({
'Access-Control-Allow-Origin': '*',
'Content-Type': 'text/plain'
});
return new Response(count.toString(), { headers });
}

// 原有的随机图片逻辑
const objects = await bucket.list({ prefix: prefix });
const items = objects.objects;

if (items.length === 0) {
return new Response('No images found', { status: 404 });
}

const randomItem = items[Math.floor(Math.random() * items.length)];
const object = await bucket.get(randomItem.key);

if (!object) {
return new Response('Image not found', { status: 404 });
}

const headers = new Headers();
headers.set('Content-Type', object.httpMetadata.contentType || 'image/jpeg');

return new Response(object.body, { headers });
} catch (error) {
console.error('Error:', error);
return new Response('Internal Server Error', { status: 500 });
}
},
};

旧代码:

export default {
async fetch(request, env, ctx) {
// R2 bucket 配置
const bucket = env.MY_BUCKET;

try {
// 列出 /ri/h 目录下的所有对象
const objects = await bucket.list({ prefix: 'ri/h/' });

// 从列表中随机选择一个对象
const items = objects.objects;
if (items.length === 0) {
return new Response('No images found', { status: 404 });
}
const randomItem = items[Math.floor(Math.random() * items.length)];

// 获取选中对象
const object = await bucket.get(randomItem.key);

if (!object) {
return new Response('Image not found', { status: 404 });
}

// 设置适当的 Content-Type
const headers = new Headers();
headers.set('Content-Type', object.httpMetadata.contentType || 'image/jpeg');

// 返回图片内容
return new Response(object.body, { headers });
} catch (error) {
console.error('Error:', error);
return new Response('Internal Server Error', { status: 500 });
}
},
};

  1. 点击左侧的文件图标QmQGQTiTXSESU2TSJ6tc3KrzWU4KABKqn6QZ1GdWqKnWmc.webp
  2. wrangler.toml中填入:
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "114514"
  1. 保存修改,点击右上角的部署QmP7hXdtenrJrzJRRePHQATGtyAsZEr5MkMsboXvmNUxTx.webp
  2. 在设置 – 变量找到 R2 存储桶绑定,添加你的存储桶,变量名即上文的MY_BUCKETQmStitSyATnA8sY9tTgZaXXqmqkGPUtZmMxn9KjbFQzgTc.webp
  3. 在设置 – 触发器添加你的自定义域名以便访问QmUMxtkCiKsgFw8afRUGREFztXE9D5W6FmCbAUB7DaVH5o.webp

    QmPF9iCoq6n8Jj2Z6kPkdJSCm45VJystZoYcir55yceCQo.webp

  4. 访问效果,每次刷新都不一样QmQgEdjXxF9oph2jYKzFMJToX9WfG11jUmPiNJnjhYVN4N.webp

通过使用 HTML 的 <img> 标签引用即可达到开头的效果#

如:<img src="你的域名" alt="">

原创文章,作者:mantou,如若转载,请注明出处:https://v2ez.com/1431.html

(0)
mantoumantou
上一篇 2025年5月4日
下一篇 2025年5月29日

相关推荐

  • 解锁ChatGPT,给你的vps添加原生IP

    ChatGPT现状ChatGPT目前封锁了绝大多数的数据中心IP,倘若你现在正好在使用vps作为主力代理,那么应该会在ChatGPT首页看到无法使用的封锁消息!现在,又有了一个新的…

    代码程序 2023年5月2日
  • Typecho 博客 服务器每2天定时备份脚本

    #  crontab -e    添加定时任务  apt install p7zip  安装 7z压缩工具#  1 1  */2  *   *   /root/auto_backu…

    2021年8月21日
  • 部署一个无需科学环境的谷歌 Gemini Pro Chat

    很多人NAS不具备谷歌环境以及没有公网IP,访问不太方便,所以有些小伙伴提出能不能做个免科学环境又可以外网访问的,答案是可以的,如果你已经具备了这些条件,那就跟我一起动手来部署吧。…

    2024年1月12日
  • 给别人发送图片获取别人IP小技巧

    只需要用到cloudflare 把域名解析到機子上,套上cflare 防火牆規則添加 完整uri包含自己域名 ,動作 封鎖 域名後面隨便寫一個路徑,用來識別對方,比如https:/…

    2021年4月4日
  • 数种动漫和风景壁纸随机API,你值得拥有!

    如果你想找动漫图但是百度图片质量参差不齐,如果你想在网站做随机壁纸,可以试试这些API。 岁月小筑API 接口调用地址 https调用:https://img.xjh.me/ran…

    代码程序 2021年4月27日
  • 富士 XF56mm F1.2 R WR

    富士 XF56mmF1.2 R WR 最近买了一只镜头,主要原因是X100V 夜拍能力太差,晚上拿起相机想快速拍一张的时候大概率是糊的,要么就拉高ISO 全是噪点。对富士镜头群不了…

    2023年9月7日
  • Gemini 给VPS剩余价值计算器换了皮肤

    花了几小时(主要是修改),给VPS剩余价值计算器 糊了个新UI: 感兴趣的可以自取,提供了 nodejs 和 纯html 2个版本:(适配了深浅色和移动设备) 项目地址:https…

    2026年1月12日
  • 在 GitHub 中隐藏自己的邮箱地址

    如何找到Github用户的邮箱 在介绍隐藏前首先咱们要知道,如何查看开发者的邮箱。 情况一 :对方主页上写了邮箱 这种最简单,大部分的开发者都会在Github主页留下自己的联系邮箱…

    2024年9月20日
  • 利用jsdelivr和github搭建免费又好用的全球节点CDN

    什么是jsDelivr 官网地址:https://www.jsdelivr.com/众所周知国内一些如阿里云,腾讯云,七牛云,又拍云超过一定额度都会产生费用,我记得几年前用七牛云一…

    2021年3月27日
  • url/utctime/繁体转简体的在线工具

    有时候在标题栏复制 url ,中文会变成%E8 ,总觉得看起来很别扭,就随手写了一个转换工具。 utctime 没什么好说的,烂大街的整形日期转换。 繁体转简体是因为我看一些繁体 …

    2023年12月28日

发表回复

登录后才能评论