FIT2CLOUD
API 图库 的图标

API 图库

174
54

接入外部图片 API,在前端实时展示图库资源,图片不落本地存储;支持多数据源、定时同步与后台管理。

API 图库

接入任意外部图片 API,定时拉取素材并在前台展示。图片只缓存地址等元数据,文件始终由第三方图源提供,不下载、不写入附件库,不占用一点本地存储。

应用市场填写信息

字段 值
应用名称 API 图库
标识 api-gallery
版本 1.4.2
Halo 版本要求 >= 2.20.0
协议 MIT
开源 是(仓库 https://github.com/lu7875/halo-plugin-api-gallery)
作者 kbmp(https://github.com/lu7875)
主页 https://github.com/lu7875/halo-plugin-api-gallery
源码仓库 https://github.com/lu7875/halo-plugin-api-gallery
问题反馈 https://github.com/lu7875/halo-plugin-api-gallery/issues
一句话简介 接入外部图片 API,在前台实时展示图库资源;图片不落本地存储,支持多数据源、定时同步与滚动更新

AI 使用声明:本项目在开发过程中使用了 AI 辅助编码(AI-substantial)。提交上架前已由开发者对权限边界、对外 HTTP 请求、诊断接口脱敏与上架材料做人工复查,并在 Halo 2.27.1 实机安装验证。1.4.1 / 1.4.2 针对审核意见,人工复测了图源 302/307 跳转目标逐跳校验(内网/回环/云元数据/非 http 协议均拒绝、合法跳转与相对路径正常跟随)、302 随机图源 Location 与随机 JSON 图片地址的二次校验、初始地址 SSRF 校验,以及随机源多轮定时同步的滚动更新与去重行为。

功能特性

  • 零存储占用 — 只保存 {id, url, title, tags, source} 元数据,图片由访客浏览器直连图源 CDN,不创建附件、不消耗磁盘
  • 多数据源 — 后台可添加任意数量的图源,各自独立开关、独立统计张数与错误
  • 三种响应结构自适应 — 自动识别顶层数组、{items:[...]} 包裹、单个对象(随机图接口);也可手动指定
  • 支持 302 随机图源 — 没有列表接口、每次请求直接跳转到随机图的源(如 random-pictures 类站点),插件会重复采样并去重,攒成图集
  • 定时同步 + 周期热更新 — 默认 60 分钟一轮(可调 5–1440 分钟),后台改完周期保存即刻生效,不用重启插件
  • 滚动更新(1.3.0) — 随机类图源每轮同步都会换进一批新图并淘汰最老的,素材持续更新,不会攒满就静止
  • 对接官方「图库管理」 — 可把图片地址写成 Photo 记录,直接在后台 /console/photos 与主题 /photos 页面呈现,依然不占存储
  • 前台展示页随包提供(1.4.0) — 瀑布流 + 懒加载 + 灯箱 + 按源筛选的展示页直接打进 jar,启用即可访问
  • 访客可读 — 自动为匿名用户放行只读接口,前台页面无需登录即可展示(可关闭)
  • 开箱即用 — 未配置时内置示例图源,装完启用就有图

安全设计(1.4.0 重点)

本插件会根据后台配置的地址向外部发起 HTTP 请求,因此做了三层边界:

层面 措施
对外请求 每次请求前执行 SSRF 校验:仅允许 http/https,拒绝回环、私有网段(10/8、172.16/12、192.168/16)、链路本地 169.254/16(含云元数据端点)、IPv6 唯一本地 fc00::/7、组播与广播;域名解析后的每个 IP 都要过网段检查
跳转防护(1.4.1) 关闭自动跟随跳转,改为手动逐跳跟随;每一跳跳转前重新校验协议/主机/解析 IP,跳转目标必须同样是公网 http/https,限制最大 5 跳防重定向循环
响应地址校验(1.4.2) 302 随机图源的 Location、200 兜底文本、随机单张 JSON 里的图片地址,先归一为绝对 URL 再执行同一套完整 SSRF 校验;不合法直接丢弃,不写入缓存、图库或前台页面
接口权限 接口拆成公开只读组(api.gallery.halo.run,可对访客放行的只有 /items、/random)与管理诊断组(console.gallery.halo.run,含 /sources、/diagnose、/sync、/push-to-photos、/photos,永不对匿名放行)
诊断脱敏 /diagnose 不返回响应正文、字段值、异常消息与堆栈;只回 httpStatus、contentType、bodyLength、looksLikeJson、rows / rowFields(仅字段名)与异常类名
写操作隔离 写入图库的记录统一带 api-gallery.kbmp.club/managed=true 标签,撤回时只删这一批,不动手工上传的照片

安装使用

  1. 下载 api-gallery-1.4.2.jar(GitHub Releases 或 Halo 应用市场)
  2. 后台 → 插件 → 上传安装并启用
  3. 插件详情 → 设置 → 「API 数据源」添加图源,保存后约 1–3 秒完成首次同步
  4. 前台调用接口或打开随包的展示页即可看到图片

前台展示页(随 jar 提供)

启用插件后直接访问:

https://<你的站点>/plugins/api-gallery/assets/static/gallery.html

也可把它放进主题目录,或用 iframe 嵌入任意页面。该路径由插件内置的静态资源代理提供,
不是 /plugins/api-gallery/static/...。

添加图源

字段 示例 说明
名称 派次元 显示用,也是同步进图库时的分组名
API 地址 https://t.paiii.cn/api/random?format=json 支持列表接口、随机图接口、302 跳转;必须是公网地址
响应结构 自动识别 / 随机单张 JSON / 302 跳转 不确定就选自动识别
采样次数 30 随机类图源每轮请求多少次(上限 200)
最多累积 60 该源图池大小,达到后淘汰旧图(上限 5000)

采样采用串行 + 120 ms 间隔,30 次约 3–8 秒,不会把免费图源打挂。

支持的图源类型

类型 典型地址 行为
固定列表 https://t.paiii.cn/api/list 每次返回内容一致,同步多少次都是同一批图
随机单张 JSON https://t.paiii.cn/api/random?format=json 每次返回不同图,采样累积成图集
302 跳转 https://api.6045833.xyz/dongman 读取跳转地址,重复采样去重后成图集

实测:/api/random?format=json 采样 12 次得 12 张不重复(约 2.9 秒),api.6045833.xyz 采样 12 次得 12 张不重复(约 3.4 秒)。

与「图库管理」插件的关系

两者定位不同,可配合使用:

  • 图库管理(plugin-photos)负责存储与管理照片,提供 /photos 路由与模板
  • API 图库负责从外部图源取素材,不存储文件

开启「同步到图库管理」后,本插件会把图片地址写成 Photo 记录,于是后台 /console/photos 和主题 /photos 页面都能展示这些外链图,磁盘占用仍为零。写入的记录带 api-gallery.kbmp.club/managed=true 标签,撤回时只删这一批,不会动你手工上传的照片。

对外接口

公开只读组(可对访客放行)

基址:/apis/api.gallery.halo.run/v1alpha1

方法 路径 说明
GET /items?source=&page=1&size=20 分页返回图片元数据
GET /random?source= 随机一张,适合做站点头图或背景

管理诊断组(需后台登录,不对匿名开放)

基址:/apis/console.gallery.halo.run/v1alpha1

方法 路径 说明
GET /sources 各图源张数、上次/下次同步时间、错误原因
GET /diagnose 逐个源实探一次,返回脱敏状态
POST /sync 手动触发同步
POST /push-to-photos 手动推送到图库
DELETE /photos 撤回本插件写入图库的记录

1.3.1 及以前这些管理接口位于 api.gallery.halo.run 组,1.4.0 起迁到 console.gallery.halo.run。

注意事项

  • 依赖第三方图源:图源挂了前端就加载不出图,已同步的元数据仍在,图源恢复后自动可用
  • 缓存是进程内的:重启 Halo 后缓存清空,启动后会自动重新同步,无需人工干预
  • 图源需开放跨域:图片由访客浏览器直连图源,图源未开放 CORS 时前端会加载失败
  • 图源必须是公网地址:内网/回环地址会被 SSRF 防护主动拒绝(安全策略,非缺陷)
  • 同步周期不宜过短:建议不低于 5 分钟,太频繁可能被图源限流
  • 版权:图片版权归各图源及其投稿者,商用前请自行确认授权

常见问题

Q:设置了自动同步,图片却一直没变?

先看 /sources 接口:intervalMinutes 是当前实际生效的周期,lastSync/nextSyncAt 是上次/下次同步时间,secondsUntilNextSync 为 -1 说明周期任务没排上。

两种典型情况:

  1. 周期没生效 — 1.2.0 起保存设置会立即按新周期重新排期,无需重启
  2. 同步了但内容本就不变 — 固定列表类图源每次返回完全相同的内容,同步一万次也是同一批图。想要素材有变化,请改用随机类图源

Q:前台请求 /items 返回 302?

公开只读组未对访客放行。确认「同步设置 → 允许访客查看图库」已开启并保存;若自动授权失败,到后台 → 用户 → 角色 → 匿名角色手动勾选相关权限。

Q:同步后图源报错,提示 URL 协议或地址被拦?

这是 SSRF 防护生效了。图源必须是可从公网访问的 http/https 地址;内网、回环、云元数据地址一律拒绝。

Q:同步后图源报错?

看 /sources 里该源的 error 字段,常见原因是地址不通、返回非 JSON(例如随机图接口漏了 ?format=json,会返回图片二进制),或响应结构与所选解析方式不匹配。

Q:gallery.html 访问 404?

请访问 /plugins/api-gallery/assets/static/gallery.html(注意有 assets/static),
不是 /plugins/api-gallery/static/gallery.html。


讨论(0)

这是一个开源应用,我们推荐优先在开源仓库中提交 issue,以便开发者更好地接收和跟进问题。

去提交 issue