主题素材可放任意 S3 兼容存储,生成器内测通后一键上传
素材位置改成两选一(本地随二进制 / 自行填 Endpoint 的 S3 兼容存储), R2、MinIO、B2、OSS-COS 的 S3 端点都只差 Endpoint/Region/路径风格。 - serve.py:手写 SigV4(PUT/GET/DELETE/HEAD),新增 /api/s3/test 与 /api/s3/upload。测试连接依次验连通、写权限、读回一致、匿名可读, 失败把 S3 的 <Code> 翻成可执行的建议;上传带 immutable 缓存头。 - index.html:新增「素材托管」面板(模式切换 + 7 个字段 + 测试/上传按钮), 上传集合与导出共用 usedAssetIds();成功后自动回填「素材前缀」。 密钥只进 sessionStorage 与内存,不进草稿/工程 json/导出 zip。 - 修:usedAssetIds 返回 Set,误用 length/map 导致「还没有素材」。 - 修:字段填完 700ms 内刷新会丢配置 → 失焦与模式切换时立即落盘。 - 自检:check_sigv4.py 与 aws-sdk-go-v2 signer 逐字节对拍(6/6), selftest_upload.py 起假 S3 跑通测试连接→上传→读回(16 项), mock_s3.py 供手动点面板用。
This commit is contained in:
+37
-17
@@ -1,4 +1,9 @@
|
||||
# 把主题素材放到对象存储(R2 / OSS)
|
||||
# 把主题素材放到对象存储(任意 S3 兼容)
|
||||
|
||||
这里的「对象存储」不特指某一家:Cloudflare R2、自建 MinIO、Backblaze B2、
|
||||
阿里云 OSS 的 S3 兼容端点、腾讯云 COS 的 S3 兼容端点都走同一套 SigV4,
|
||||
差别只在 Endpoint、Region、是否路径风格。**放本地还是放对象存储,由部署者自己决定** ——
|
||||
主题生成器里「素材托管」就是这两选一。
|
||||
|
||||
现状:主题素材在 `static/images/themes/<slug>/`,通过 `static/fs.go` 的 `//go:embed images/themes`
|
||||
随二进制发布。好处是部署即生效、不依赖外部服务;代价是**换一张图就要重新编译部署**,
|
||||
@@ -12,32 +17,46 @@
|
||||
|
||||
---
|
||||
|
||||
## A. 生成器直接写绝对地址(已支持,推荐)
|
||||
## A. 生成器直接写绝对地址 + 就近上传(已支持,推荐)
|
||||
|
||||
`dev/theme-builder` 的导出面板新增「**素材前缀**」:
|
||||
`dev/theme-builder` 左侧「**素材托管**」有两个选项:本地(随二进制)/ S3 兼容存储。
|
||||
|
||||
选 S3 后填:
|
||||
|
||||
```
|
||||
素材前缀 https://cdn.example.com/themes
|
||||
Endpoint https://<账号>.r2.cloudflarestorage.com ← MinIO / B2 / OSS / COS 填各自的
|
||||
Region auto ← R2 用 auto;MinIO 常为 us-east-1
|
||||
桶名 my-theme-assets
|
||||
路径前缀 themes
|
||||
公开前缀 https://cdn.example.com/themes ← 留空 = 按 Endpoint 推导
|
||||
Access Key / Secret Key
|
||||
```
|
||||
|
||||
留空 = 沿用 `/static/images/themes/<slug>/`(图片随二进制发布,和以前一样)。
|
||||
填了 = 导出的 CSS 里所有图片地址变成 `https://cdn.example.com/themes/<slug>/<id>.webp`。
|
||||
**前缀里不要带 slug**,slug 由导出时自动拼在后面。
|
||||
然后:
|
||||
|
||||
图片照旧打进 zip(`static/images/themes/<slug>/*.webp`),只是用途从「放进仓库」变成
|
||||
「传到对象存储的 `<前缀>/<slug>/` 下」。INSTALL 文案会跟着变,直接写清楚往哪传。
|
||||
1. **测试连接** —— `HEAD` 桶(连通+凭据)→ `PUT` 探针(写权限)→ `GET` 读回(内容一致)
|
||||
→ 匿名 `GET`(能不能被浏览器直接读到)→ 删除探针。失败会把 S3 的 `<Code>` 翻成人话。
|
||||
2. **上传素材** —— 逐张 PUT 本次主题引用到的图,键为 `<路径前缀>/<slug>/<id>.webp`,
|
||||
带 `public, max-age=31536000, immutable`。成功后自动把导出用的「素材前缀」填好。
|
||||
|
||||
上传经本机 `serve.py` 代理(`/api/s3/test`、`/api/s3/upload`),浏览器不直连对象存储:
|
||||
**不需要给桶配 CORS**,密钥只在当前标签页的 sessionStorage 与内存里,
|
||||
不进草稿、不进工程 json、不进导出 zip。
|
||||
|
||||
不想用面板也行,导出的 zip 里图片照旧在 `static/images/themes/<slug>/*.webp`,
|
||||
用任何 S3 客户端推上去即可:
|
||||
|
||||
```bash
|
||||
aws s3 sync static/images/themes/shiroko/ s3://my-bucket/themes/shiroko/ \
|
||||
--endpoint-url https://<你的 Endpoint> --cache-control "public, max-age=31536000, immutable"
|
||||
sed -i 's#/static/images/themes/shiroko/#https://cdn.example.com/themes/shiroko/#g' \
|
||||
static/css/themes/shiroko.css # 已有主题不想重导时,等价于「填前缀再导一次」
|
||||
```
|
||||
|
||||
- 优点:零服务端改动、零跳转、缓存最优(CDN 直接命中);
|
||||
- 缺点:域名烘焙进 CSS —— 换域名/换路径要**重新导出**(旧主题可以用 `sed` 批量替换);
|
||||
- 仓库里可以删掉 `static/images/themes/<slug>/` 来缩小编译产物,**确认 CSS 已是绝对地址**再删。
|
||||
|
||||
命令行等价做法(已有主题不想重导):
|
||||
|
||||
```bash
|
||||
sed -i 's#/static/images/themes/shiroko/#https://cdn.example.com/themes/shiroko/#g' \
|
||||
static/css/themes/shiroko.css
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## B. 应用内 301 跳转(配置驱动,CSS 一行都不用改)
|
||||
@@ -107,6 +126,7 @@ func themeAssetRedirect() flamego.Handler {
|
||||
|
||||
## 建议
|
||||
|
||||
- 只是想让部署产物变小、换图不用重编译 → **A**(生成器填前缀,最省事,缓存也最好)。
|
||||
- 只是想让部署产物变小、换图不用重编译 → **A**(生成器里配好 S3、测通、一键上传,最省事,缓存也最好)。
|
||||
- 想保留「素材可以随时换、CSS 不用重发」的灵活性 → **B**(配一个 `asset_base`,接受多一跳)。
|
||||
- 站点已经在 Cloudflare 上、且愿意在边缘配规则 → **C**(最干净,但迁移成本在运维侧)。
|
||||
- 就用本地目录、不想依赖任何外部服务 → **什么都不用做**(默认行为,素材随二进制发布)。
|
||||
|
||||
Reference in New Issue
Block a user