前言

零成本,免费图床,图片存放著名通讯服务应用 Telegram 宣布推出内容发布平台 Telegraph 上,使用 Github 项目 Telegraph-Image 通过 Cloudflare Page 搭建部署。

特性

  1. 无限图片储存数量,你可以上传不限数量的图片
  2. 无需购买服务器,托管于 Cloudflare 的网络上,当使用量不超过 Cloudflare 的免费额度时,完全免费
  3. 无需购买域名,可以使用 Cloudflare Pages 提供的*.pages.dev的免费二级域名,同时也支持绑定自定义域名
  4. 支持图片审查 API,可根据需要开启,开启后不良图片将自动屏蔽,不再加载
  5. 支持后台图片管理,可以对上传的图片进行在线预览,添加白名单,黑名单等操作

如何部署

提前准备

你唯一需要提前准备的就是一个 Cloudflare 账户 (如果需要在自己的服务器上部署,不依赖 Cloudflare,可参考#46

手把手教程

简单 3 步,即可部署本项目,拥有自己的图床

  1. Fork 本仓库 (注意:必须使用 Git 或者 Wrangler 命令行工具部署后才能正常使用,文档)
  2. 打开 Cloudflare Dashboard,进入 Pages 管理页面,选择创建项目,选择连接到 Git 提供程序
    2

3

  1. 按照页面提示输入项目名称,选择需要连接的 git 仓库,点击部署站点即可完成部署

:::info
这时图库就已经能用了,如下图方式访问站点
4
:::

绑定自定义域名

如果你自己的域名通过 Cloudflare 管理 (有免费的CND缓存图片,可降低图片访问次数)
在 pages 的自定义域里面,绑定 cloudflare 中存在的域名,在 cloudflare 托管的域名,自动会修改 dns 记录
2
如果域名不通过 Cloudflare 管理,需要增加一条 CNAME 解析记录到站点域名上
3

开启图片审查

  1. 请前往https://moderatecontent.com/ 注册并获得一个免费的用于审查图像内容的 API key
  2. 打开 Cloudflare Pages 的管理页面,依次点击设置环境变量添加环境变量
  3. 添加一个变量名称ModerateContentApiKey为你刚刚第一步获得的API key,点击保存即可
    :::warning
    注意:由于所做的更改将在下次部署时生效,你或许还需要进入部署页面,重新部署一下该本项目
    6
    :::
    开启图片审查后,因为审查需要时间,首次的图片加载将会变得缓慢,之后的图片加载由于存在缓存,并不会受到影响
    3

配置后台管理

默认是关闭的,如需开启请部署完成后前往后台依次点击设置->函数->KV 命名空间绑定->编辑绑定->变量名称填写:img_url KV 命名空间 选择你提前创建好的 KV 储存空间,开启后访问 http(s)://你的域名/admin 即可打开后台管理页面

变量名称KV 命名空间
img_url选择提前创建好的 KV 储存空间


后台管理页面有登录验证功能,默认也是关闭的,如需开启请部署完成后前往后台依次点击设置->环境变量->为生产环境定义变量->编辑变量 添加如下表格所示的变量即可开启登录验证

变量名称
BASIC_USER =<后台管理页面登录用户名称>
BASIC_PASS =<后台管理页面登录用户密码>

:::warning
注意:由于所做的更改将在下次部署时生效,你或许还需要进入部署页面,重新部署一下该本项目
6
:::

后台管理功能

新增图片总数量统计
可在后台顶部查看记录中的图片数量

新增图片文件名搜索
可在后台搜索框使用图片文件名称,快速搜索定位需要管理的图片

新增图片状态显示
可在后台查看图片当前的状态{ "ListType": "None", "TimeStamp": 1673984678274 }
ListType 代表图片当前是否在黑白名单当中,None 则表示既不在黑名单中也不在白名单中,White 表示在在白名单中,Block 表示在黑名单中,TimeStamp 为图片首次加载的时间戳,如开启的图片审查 API,则这里还会显示图片审查的结果用 Label 标识

新增黑名单功能
可在后台手动为图片加入黑名单,加入黑名单的图片将无法正常加载

新增白名单功能
可在后台手动为图片加入白名单,加入白名单的图片无论如何都会正常加载,可绕过图片审查 API 的结果

新增记录删除功能
可在后台手动删除图片记录,即不再后台显示该图片,除非有人再次上传并加载该图片,注意由于图片储存在 telegraph 的服务器上,我们无法删除上传的原始图片,只能通过上述第 6 点的黑名单功能屏蔽图片的加载

新增程序运行模式:白名单模式
在该模式下,只有被添加进白名单的图片才会被加载,上传的图片需要审核通过后才能展示,最大程度的防止不良图片的加载,如需开启请设置环境变量:WhiteList_Mode=="true"

新增后台图片预览功能
可在后台预览通过你的域名加载过的图片,点击图片可以进行放大,缩小,旋转等操作

限制

  1. 由于图片文件实际存储于 Telegraph,Telegraph 限制上传的图片大小最大为 5MB
  2. 由于图片文件实际存储于 Telegraph,你只能删除图片记录,无法真正删除文件
  3. 由于使用 Cloudflare 的网络,图片的加载速度在某些地区可能得不到保证
  4. Cloudflare KV 每天只有 1000 次的免费写入额度,每有一张新的图片加载都会占用该写入额度,如果超过该额度,图片管理后台将无法记录新加载的图片
  5. 每天最多 100,000 次免费读取操作,图片每加载一次都会占用该额度(在没有缓存的情况下,如果你的域名在 Cloudflare 开启了缓存,当缓存未命中时才会占用该额度),超过黑白名单等功能可能会失效
  6. 每天最多 1,000 次免费删除操作,每有一条图片记录都会占用该额度,超过将无法删除图片记录
  7. 每天最多 1,000 次免费列出操作,每打开或刷新一次后台/admin 都会占用该额度,超过将进行后台图片管理
    绝大多数情况下,该免费额度都基本够用,并且可以稍微超出一点,不是已超出就立马停用,且每项额度单独计算,某项操作超出免费额度后只会停用该项操作,不影响其他的功能,即即便我的免费写入额度用完了,我的读写功能不受影响,图片能够正常加载,只是不能在图片管理后台看到新的图片了。

如果你的免费额度不够用,可以自行向 Cloudflare 购买 Cloudflare Workers 的付费版本,每月$5 起步,按量收费,没有上述额度限制

使用 Cloudflare Access 保护

个人使用建议再加一层 Cloudflare Access 设置

访问页面弹出如下
2
填写自己邮箱,点击发送,收到邮件,再将邮件内的验证码填写如下
2
登录后才能进去上传文件

开启方式

在如下图位置开启策略,全部默认
2
它会新增一个应用的认证
2

:::warning
记得要重新部署
::

验证

ctrl+shift+n 打开浏览器无痕窗口,访问网站,出现前面效果图模样就算成功

修改标题与左下角提示

在 index.html 文件的 html 与 body 结尾标签中间添加如下代码,可调整标题与左下角提示

<style type="text/css">
.main .title {
  display:none;
}
.footer {
  display:none;
}
</style>
<script>
setTimeout(function() {
  // 删除原标题
  document.getElementsByClassName("title")[0].remove();
  // 添加新标题
  document.getElementsByClassName("main")[0].insertAdjacentHTML('afterbegin',`<div class="title" data-v-5e6831cc style="color:white;display:block"><a style="color:white" href="https://xirizhi.cn">昔日长廊博客</a>私人图床,<a style="color:white" href="https://xirizhi.cn/?p=1710567769974">自建教程</a></div>`);
  // 删除原提示
  document.getElementsByClassName("footer")[0].remove();
  // 添加新提示
  document.getElementsByClassName("container")[0].insertAdjacentHTML('beforeend',`<div class="footer" style="color:white;display:block">
    通过 <a style="color:white" href="https://github.com/cf-pages/Telegraph-Image" target="_blank" data-v-5d5649c4>Telegraph-Image</a> 的代码库搭建
  </div>`);
}, 700); // 延迟的毫秒数
</script>

:::warning
注意:由于所做的更改将在下次部署时生效,你或许还需要进入部署页面,重新部署一下该本项目
:::

防盗链设置

将 functions/file/[id],js 文件修改成如下

...// 省略
const url = new URL(request.url);

// 新增部分
let allowedDomains = context.env.ALLOWED_DOMAINS;
console.log(allowedDomains);
if (allowedDomains != null && allowedDomains != "") {
  allowedDomains = allowedDomains.split(",");
  console.log(allowedDomains);
  let Referer = request.headers.get('Referer');
  console.log(Referer);
  if(typeof request.headers.get('Referer') == "undefined" ||Referer == null || Referer == ""){
      return Response.redirect("https://gcore.jsdelivr.net/gh/guicaiyue/FigureBed@master/MImg/20240321211254095.png", 302);
  }else {
    let refererUrl = new URL(Referer);
    if (!allowedDomains.includes(refererUrl.hostname)) {
      return Response.redirect("https://gcore.jsdelivr.net/gh/guicaiyue/FigureBed@master/MImg/20240321211254095.png", 302);
    }
  }
}
// 结束

const response = fetch('https://telegra.ph/' + url.pathname + url.search, {
...// 省略

然后像前面一样配置环境变量,增加一个 ALLOWED_DOMAINS 就能指定域名访问了,多个用,号隔开
image.png

效果

如下图能在当前博客访问
Telegra_ph-Drag_Upload
但拷贝图片链接https://pictures.xirizhi.cn/file/836c12b33ed3e845d72ec.jpg外部打开时就会看到如下照片
20240321211254095.png

:::warning
注意:由于所做的更改将在下次部署时生效,你或许还需要进入部署页面,重新部署一下该本项目
:::

上传限制

...// 省略
const url = new URL(request.url);

// 新增部分
let uploadDomains = context.env.UPLOAD_DOMAINS;
if (uploadDomains != null && uploadDomains != "") {
uploadDomains = uploadDomains.split(",");
 let Referer = request.headers.get('Referer');
 if(typeof request.headers.get('Referer') == "undefined" ||request.headers.get('Referer') == null || request.headers.get('Referer') == ""){
    return new Response('权限不足', { status: 403 });
 }else {
  let refererUrl = new URL(Referer);
  console.log(uploadDomains);
  console.log(refererUrl.hostname);
  if (!uploadDomains.includes(refererUrl.hostname)) {
    return new Response('权限不足', { status: 403 });
  }
 }
}
// 结束

const response = fetch('https://telegra.ph/' + url.pathname + url.search, {
...// 省略

增加一个 UPLOAD_DOMAINS 就能指定域名才能上传,多个用,号隔开。

适配 Halo 插件

待续