提示词+出图打包成短链接|不花一分钱搭个带审核的图片分享站

写在前面:这是什么

Prompt Share 是我做的一个小站:把"提示词 + 出图"打包成一个短链接,发到 X / 小红书 / 微信都行。一条作品 = 一个提示词 + 多张示例图(最多 8 张)。

首页是公开画廊:访客不用登录就能逛精选和最新作品、按标签搜;登录后才能上传;分享出去的页面有一键复制提示词按钮。

为什么做这个项目

玩 AI 生图的人都有这个痛点:提示词和出图散落在各处,想分享给别人时要么截图、要么复制粘贴大段文字,体验很差。我想要的是:一条作品 = 一个提示词 + 多张示例图,打包成一个短链接,发到 X / 小红书 / 微信,对方点开就能看图、一键复制提示词拿去用。

再往前一步:如果朋友也想往里传,就得有个审核——不能谁传什么都直接上架。所以有了"管理员直发、普通用户进待审队列、管理员在 /admin 点通过"的设计;又因为不想开放公开注册(防 spam),登录直接用 Cloudflare Access 的邮箱白名单,加人就是加一行邮箱。

适合哪类人

  • AI 生图玩家:攒了一堆提示词和出图,想沉淀成可分享、可检索的作品集
  • 做 AI 内容账号的人:发图时配一句"提示词自取",链接往评论区一贴就行
  • 小团队 / 小社群:内部提示词知识库,带审核流程,不想搞注册系统
  • 想拿 Cloudflare 全家桶练手的人:单文件、无依赖、免费额度内跑,抄作业成本极低

如果你只是想找个网盘存图,这篇不适合你——这是"分享站",不是"备份盘"。

整站的架构长这样:

  • Cloudflare Worker:src/worker.js 一个文件就是前后端全部逻辑(路由、页面渲染、API),无依赖
  • KV:分享元数据、待审队列、索引(最新 / 标签 / 用户 / 精选)、限流计数器
  • R2:图片原文件,私有 bucket,不开公开访问
  • Cloudflare Access(Zero Trust):登录鉴权,不开放公开注册
  • 自定义域名:绑到 Worker 上对外服务

结构图(一张图看懂请求链路):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
        访客 / 用户
            │
            ▼
┌───────────────────────────┐
│ Cloudflare Access(门卫)  │
│ 公开区 Bypass 免登录       │
│ 写操作 Allow 邮箱白名单    │
└─────────────┬─────────────┘
              ▼
┌───────────────────────────┐
│ Worker: src/worker.js     │
│ 路由 / 页面 / API 单文件   │
│ + 二次校验 Access JWT     │
└───────┬───────────┬───────┘
        │           │
        ▼           ▼
  ┌──────────┐ ┌────────────┐
  │ KV       │ │ R2         │
  │ 元数据/  │ │ 图片原文件  │
  │ 索引/待审 │ │ 私有 bucket │
  └──────────┘ └────────────┘

读法:所有请求先过 Access(门卫)——公开路径直接放行,/upload、/admin 等必须登录;Worker 拿到请求后,读 KV 取元数据、经 R2 代理取图。图片不暴露直链,分享页的图片地址带 HMAC 签名(6 小时过期)防盗链。

图片安全与限流是这套架构自带的设计:图片走 Worker 代理(/img/:id),Referer 非本站 403、空 Referer 放行(直接打开链接、IM 内分享是正常行为);分享页图片地址带 HMAC 签名,6 小时过期;强缓存 Cache-Control: public, max-age=31536000, immutable,重复访问不回源、不消耗 R2 读取次数。限流方面,上传每 IP 每小时 20 次、图片每 IP 每分钟 120 次,都在 worker.js 顶部常量里,按需调。

为什么选这套?三句话:零服务器(不用管 VPS、不用配 Nginx)、免费额度够(见下表)、一个文件好维护(改功能只改 worker.js,push 就上线)。

用到的免费资源(截至本文发布 2026-09-30)

资源免费额度在本项目里的用途
Cloudflare Workers每天 10 万次请求跑 src/worker.js:路由、页面渲染、API
KV存 1GB,每天 10 万次读 / 1000 次写分享元数据、待审队列、四套索引、限流计数
R2每月 10GB 存储 + 100 万次写入 + 1000 万次读取,出站流量免费图片原文件(私有 bucket,不开公开访问)
Zero Trust Access50 用户以内免费登录鉴权:公开区 Bypass、写操作 Allow
Workers Builds免费连 GitHub 私有仓库,push 到 main 自动部署

说明两点:第一,额度是发布日我在 Dashboard 看到的,Cloudflare 政策会变,以你实际看到的为准;第二,唯一不免费的是域名本身(你得有一个已经接入 Cloudflare 的域名)。

为什么额度够用?图片走强缓存(immutable,重复访问不回源),KV 只存元数据不存图,Access 50 人上限对小社群绰绰有余。真超了再考虑付费,不超就一直白嫖。

准备工作

  1. 一个 Cloudflare 账号(免费账号就行)
  2. 一个已经接入 Cloudflare 的域名(后面绑自定义域名用)

第一步:建三个资源

1. 建 R2 bucket(图床)

Dashboard → R2 → Create bucket,名字 prompt-share-imgs。不要开公开访问,保持私有——图片一律走 Worker 代理出去,不暴露 R2 直链。

2. 建 KV namespace(元数据)

Workers & Pages → KV → Create namespace,名字 prompt-share。KV 里存的东西:

  • s:{id}:分享 JSON(标题、中英提示词、标签、作者、是否精选、创建时间……)
  • pending:{id}:待审 JSON(30 天过期)
  • idx:new / idx:tag / idx:user / idx:featured:最新、标签、用户、精选四套索引
  • rl:*:限流计数器

3. 建 Worker

Workers & Pages 里建一个 Worker,名字 prompt-share。代码先不贴,后面接 GitHub 自动部署一步到位。

第二步:配绑定和变量(Secret 绝不进仓库)

Workers → prompt-share → Settings → Bindings → Add binding:

  • R2 bucket → Variable name IMGS → 选 prompt-share-imgs
  • KV namespace → Variable name SHARE → 选上一步建的 namespace

Settings → Variables → Add variable:

  • Secret SIGN_SECRET = 随机字符串。本地电脑跑 openssl rand -hex 32 生成,在 Dashboard → Settings → Variables → Secrets 里添加
  • Text ADMIN_EMAILS = 管理员邮箱(多个用逗号分隔)
  • Text ACCESS_TEAM_DOMAIN / ACCESS_AUD = 建好 Access 应用后回填(见第三步),回填完点 Redeploy

重点强调:SIGN_SECRET 只放在 Dashboard 的 Secrets 里,绝不写进 wrangler.toml、绝不进仓库。走 GitHub 自动部署时,Dashboard 里已有的 Secret 会保留,不会被 CI 覆盖。

第三步:Zero Trust Access(重点:拆成两个应用)

这是整套部署里最关键的一步,也是最容易配错的一步。

为什么拆两个应用? 公开画廊要免登录、随便逛;上传、审核、管理必须登录。Access 的应用是按路径生效的,所以拆成:

应用一 prompt-share-public(Bypass,所有人免登录)

Zero Trust Dashboard → Access → Applications → 添加应用,两个域名(*.workers.dev 和你的自定义域名)各加这些路径:

  • /
  • /tag/*
  • /search*
  • /f/*
  • /img/*

应用二 prompt-share(Allow,邮箱白名单登录)

同样两个域名各加这些路径:

  • /upload
  • /mine
  • /api/*
  • /admin/*

Policy → Allow → Emails:填管理员 + 普通用户的邮箱。Access 免费版 50 用户是硬上限,加人 = 以后直接改这个 Policy 的邮箱名单,即时生效,不用动代码。

两个细节:

  1. / 是前缀匹配,会覆盖全站;登录区靠更具体的路径优先命中。配完后用无痕窗口把每个路径逐个打开验证一遍,以你实际看到的为准。
  2. 建好应用二后,把应用总览页的 AUD(一串 hex)和你的 Team Domain(如 yourteam.cloudflareaccess.com)回填到第二步的 Worker 变量里,再 Redeploy 一次。

另外 Worker 侧还会二次校验 Cf-Access-Jwt-Assertion(证书签名、aud、过期时间),就算有人绕过 Access 直接打 Worker 域名也进不来。双保险。

第四步:绑自定义域名

Workers → prompt-share → Settings → Domains → Add Custom Domain,填你的域名(比如 prompt.minispacex.com)。

注意:第三步的两个 Access 应用里,workers.dev 域名和自定义域名都要配路径,只配一个的话另一个域名上的路径鉴权会漏。

第五步:GitHub 自动部署

代码仓库是私有的,就两个文件:src/worker.js + wrangler.toml。

Dashboard 里把 GitHub 仓库连上 Workers Builds:选 main 分支,构建命令留空(单文件无依赖,不需要构建,填了构建命令反而会失败),push 到 main 自动发布。

wrangler.toml 里写好绑定(R2/KV)和普通变量(ADMIN_EMAILS、ACCESS_TEAM_DOMAIN、ACCESS_AUD),SIGN_SECRET 留在 Dashboard Secrets 里,CI 部署不会动它。

本地改完 worker.js:git push 到 main 就行。一个实战经验:如果本地 .git 丢了,直接在 GitHub 网页上上传覆盖 worker.js 也会触发 Workers Builds 自动部署,亲测可用——但 push 前最好先确认 .git 还在,别把仓库搞成裸文件堆。

功能清单

部署完你会得到这些:

  • 公开画廊首页 /:精选大图轮播(全幅、完整显示不裁切、左右滑动)+ 最新瀑布流 + 标签云 + 搜索框,免登录
  • 标签页 /tag/:tag、搜索 /search?q=:标题 / 标签 / 提示词子串搜索,近 150 条内过滤
  • 详情页 /f/:id:公开访问,一键复制当前语言提示词;中英双语一键切换
  • 多图:一条作品最多 8 张,第一张为封面;作者/管理员可编辑加图、可勾选删除(至少保留 1 张),删封面后自动提位
  • 审核流程:普通用户上传进待审队列(30 天过期),管理员在 /admin 点"通过上架 / 通过并精选 / 驳回删除";管理员上传直接上架,可设精选
  • /mine 我的作品:登录后看自己的待审 + 已上架
  • /admin:审核 + 精选管理 + 删除作品(仅管理员)

不做的:浏览/点赞统计、评论、关注。50 人社区不需要,而且 KV 免费写额度(每天 1000 次)也撑不起全量计数——这是架构取舍,不是没做完。

验证清单(部署完逐项过)

  1. 浏览器无痕打开自定义域名 → 不跳登录,直接看到画廊首页(精选 / 最新 / 标签云)
  2. 点"分享作品" → 跳 Access 登录
  3. 管理员登录 → /upload 上传一张图(标题 + 标签,勾选精选)→ 直接拿到 /f/ 链接;首页精选区出现这张
  4. 无痕打开 /f/ 链接 → 能看图,“一键复制"按钮可用
  5. /tag/xxx、/search?q=xxx 有结果;/mine 能看到自己的作品
  6. 换个普通用户邮箱登录(先加进 Policy)→ 上传 → 提示"已提交审核”,/mine 显示待审核;管理员 /admin 点"通过并精选" → 上架

最后

整套部署的核心就一句话:Worker 是唯一的可执行单元,KV + R2 是它的数据层,Access 是它的门卫,GitHub 是它的发布键。资源建一次,之后所有迭代都只是改 worker.js 再 push。

下一篇准备写 Prompt Share 的多图与审核流程是怎么设计的(KV 索引那套 idx:tag:{tag}:{inv}:{id} 的玩法),感兴趣的话可以先去站上逛逛。