零成本开一个商品展示站:我的 Cloudflare 全托管方案

不用服务器、不用数据库运维、不用懂命令行——一个跑在 Cloudflare 免费额度上的商品展示站,管理员在网页后台点点鼠标就能维护全部内容。本文介绍它的设计思路、功能全貌与安全实践,仓库已开源,Fork 即可用。

本项目主要面对:不要购物车、不要支付,就是”图 + 名字 + 价格 + 联系方式”,但图片很多、更新频繁,而且完全不会用命令行。

市面上现成的方案要么是带一堆用不上的电商功能(还得服务器),要么是纯静态站(改个商品要动代码)。于是我写了这个项目:前台负责好看,后台负责好用,基础设施全部交给 Cloudflare 免费层

整体架构

1
2
3
4
5
6
7
8
9
10
11

Cloudflare Pages(静态托管 + Pages Functions)

├── public/        前台静态页 + 后台 SPA

├── functions/     API 层(鉴权/商品/分类/设置/上传/导出)

├── Cloudflare D1  商品/分类/设置(SQLite,自带 30"时间旅行"回档)

└── Cloudflare R2  图片存储(展示前缀公开 + 原图前缀私有)

没有构建步骤、没有外部依赖。全部资源在 Cloudflare 免费额度内运行,持续成本为 0 元(除了自己的域名):D1 每天五百万次读取、R2 十 GB 存储且不收出口流量费——对一个展示站来说是几乎用不完的量。

前台展示

  • 商品卡片网格 + 分类标签(带实时数量角标)、即时搜索、按价格/上架时间正反排序
  • 详情弹窗:主图与描述里的图片自动汇成轮播,点击全屏放大,并查看详情
  • Markdown 图文描述:描述支持标题/列表/链接/多图混排,渲染器是手写的安全子集——先整体转义再生成白名单标签,从根上杜绝 XSS
  • 缺货语义:缺货商品自动排到末尾、图片蒙灰加角标,但仍然可见
  • 亮暗色主题:跟随系统自动切换,也保留手动三档开关
  • 联系浮窗:右下角客服按钮弹出二维码与咨询链接,展示站的转化入口
  • 公告弹窗:首次访问自动弹出,更新内容后会再弹一次——顺手当成”上新通知”用

后台简化设计

为了方便不会使用命令行与难的操作的人使用,整个后台都很简单,通过为https://<项目名>.pages.dev/admin或https://<域名>/admin进入后台管理页。

后台是整个项目的重心。所有操作都在网页里完成:

  • 商品增删改、一键复制(上同款新品改个图就能发布)、隐藏/显示、缺货标记
  • 拖拽排序:按住商品行拖到目标位置松手即保存,还做了全局顺序感知——筛选某个分类后拖拽,也不会打乱其他分类的编号
  • 图片三通道上传:按钮选择、直接拖拽、Ctrl+V 粘贴截图,全部支持;多张批量时逐张显示进度,方便上传图片
  • Markdown 编辑器带工具栏和实时预览;从网页或 Word 里复制带格式的内容粘贴进来,自动转成 Markdown
  • 站点设置里可以改网站名称、主页标题、网站图标、公告,上传图标和二维码即时预览
  • 随时导出 JSON 备份全部数据
  • 分类管理,可以类内单独展示排序
  • 开关图片水印,只对前台暴露有水印的图片,杜绝盗图
  • 开启整站密码方法,可以设定随机密码,也可以间隔一定时间自动更新,点击保存设置即时生效

使用方法详见lusiflowers-shop/USAGE.md at main · shview/lusiflowers-shop

图片管理

展示站的痛点是图片管理。本项目对图片管理有以下特点:

1. 增加水印 上传时在浏览器端把站名水印以斜纹平铺直接画进图片像素——而不是盖一层 CSS。截图、下载、转发都带着水印。无水印原图另存到私有前缀,R2不开放,前台无法访问。

2. 内容哈希命名 文件名是图片内容的 SHA-256 前 16 位。同一张图无论传多少次都是同一个地址:轮播自动去重、存储不重复占用。

3. 删除联动清理 删除商品时自动清理它独占引用的图片(水印图 + 原图一起删);如果某张图还被别的商品引用,会保留不误删。

4. 可选自动压图 超过 1500px 的图自动等比缩小再上传,手机直出的照片从前台加载慢的问题一并解决。

但请注意,R2的免费储存只有10G,不过按照压缩后500kb一张,可以存储超2万张图片(因为原图与加水印的各一份所以为超1万张不同的图片),并且超出的额度非常便宜,仅0.015 美元/GB-月

安全方面

上线前使用AI做了一轮 31 项渗透测试:

  • 未认证调用全部写接口(增删改商品/设置/上传/导出)→ 全部 401
  • 伪造与篡改会话 Cookie、HMAC 签名猜测 → 全部无效
  • 路径变体绕过(大小写、双斜杠、编码、方法覆盖头)→ 全部拦截
  • SQL 注入 → 参数化查询化解
  • 整站访问密码:开启后商品数据全接口锁死;访问码 8 位 43 亿组合 + 失败 800ms 强制延迟;连”开了访问密码后 OG 分享标签会不会泄露标题首图”都测了——不会

管理员密码与签名密钥只存在于 Cloudflare 环境变量里,仓库不含任何凭据。

备份相关

D1 自带 Time Travel:过去 30 天内任意一分钟的数据状态都能在控制台一键回档,免费且默认开启——比任何自建定时备份都可靠。图片在 R2 高持久存储,想更稳可以打开对象版本控制防误删。后台的导出 JSON 作为最后一道兜底。

适用群体

  • 手工艺品 / 定制商品 / 摄影作品 / 花艺烘焙……任何”重图片展示、轻交易” 的站点
  • 需要给客户预览但不公开的场景:整站访问密码 + 动态访问码,发一个码给客户就能看,到期自动失效
  • 想学 Cloudflare 全家桶的人:这个项目覆盖了 Pages、Functions、D1、R2 四件套的典型用法,代码量小、无依赖,读起来不费劲

部署要多久

照着 README 走,半小时左右:建 D1 建桶连 Git 设置两个环境变量,完事。 Fork 之后把 wrangler.toml 里的资源 ID 换成自己的就能跑。

本文未涉及到什么


如果你也有”就想好好展示一下我的东西”的需求,欢迎 Fork。遇到问题开 issue,或者告诉我你还想要什么功能——这个项目的下一站,由使用它的人决定。


零成本开一个商品展示站:我的 Cloudflare 全托管方案
https://shview.top/2026/08/16/零成本开一个商品展示站:我的 Cloudflare 全托管方案/
作者
Shview
发布于
2026年8月16日
许可协议