feat: 头像支持 GIF——跳过裁剪直接上传,原始字节存储保留动画 #11

Open
dsh wants to merge 2 commits from dsh/go_blog:feat/avatar-gif into main
Contributor

变更

头像上传支持 GIF:选择 GIF 时不再裁剪弹窗,判定大小后直接上传原始文件(保留动画,不做 canvas 转码)。

客户端(templates/pages/profile.html)

  • 选中图片为 GIF(MIME 或 .gif 后缀)时跳过硬编码/裁剪流程,直接上传原始字节;
  • 上传前按 10 MiB 大小判断(与服务端默认限制一致;服务端仍按平台策略强制校验),超限给出提示;
  • 上传+预览+导航头像更新逻辑抽为 uploadAvatarBytes(blob, filename),裁剪流(avatar.jpg)与 GIF 直传共用。

服务端(handlers/profile.go UploadAvatar)

  • GIF(白名单内扩展名 + 魔数校验通过,配置 MIME=image/gif)跳过 256x256 缩放与 JPEG 重编码,原始字节直存;files 行 ext=.gif / mime=image/gif
  • 其他图片类型(jpeg/png/webp)行为不变:缩放 + JPEG 重编码。

测试

新增 TestAvatarUploadGifStoredRaw:原始字节一致性(磁盘内容 == 上传字节)、stored_name = 原字节 SHA-256、files 行元数据与归属者断言。go build / go vet / 全量测试通过。

依赖

本分支基于 #10(更换头像后 header 样式异常的修复,profile.html 依赖其 headerAvatarWrap 标记)之上。建议先合并 #10 再合并本 PR;两者各自 mergeable,顺序合并无冲突。

## 变更 头像上传支持 GIF:选择 GIF 时**不再裁剪弹窗**,判定大小后**直接上传原始文件**(保留动画,不做 canvas 转码)。 ### 客户端(templates/pages/profile.html) - 选中图片为 GIF(MIME 或 .gif 后缀)时跳过硬编码/裁剪流程,直接上传原始字节; - 上传前按 10 MiB 大小判断(与服务端默认限制一致;服务端仍按平台策略强制校验),超限给出提示; - 上传+预览+导航头像更新逻辑抽为 `uploadAvatarBytes(blob, filename)`,裁剪流(avatar.jpg)与 GIF 直传共用。 ### 服务端(handlers/profile.go UploadAvatar) - GIF(白名单内扩展名 + 魔数校验通过,配置 MIME=image/gif)**跳过 256x256 缩放与 JPEG 重编码**,原始字节直存;files 行 `ext=.gif` / `mime=image/gif`; - 其他图片类型(jpeg/png/webp)行为不变:缩放 + JPEG 重编码。 ### 测试 新增 `TestAvatarUploadGifStoredRaw`:原始字节一致性(磁盘内容 == 上传字节)、stored_name = 原字节 SHA-256、files 行元数据与归属者断言。`go build` / `go vet` / 全量测试通过。 ## 依赖 本分支基于 **#10**(更换头像后 header 样式异常的修复,profile.html 依赖其 `headerAvatarWrap` 标记)之上。建议先合并 #10 再合并本 PR;两者各自 mergeable,顺序合并无冲突。
dsh added 2 commits 2026-08-28 20:33:48 +08:00
旧逻辑在头像上传成功后把整个 avatarBtn 按钮的 innerHTML 换成单个
<img>:头像圆形容器(w-8 h-8 rounded-full)、用户名 span 全部丢失,
头像失去圆形裁剪与边框、布局错乱,直到刷新后服务端重新渲染才恢复。

- base.html:头像是像圆形容器加 id="headerAvatarWrap"(服务器渲染结构
  不变,仅加标记)
- profile.html:上传成功后仅更新容器内容(img/svg → 新头像),
  保留按钮结构与用户名文本
- 客户端(profile.html):选中 GIF 时不进入裁剪弹窗,直接上传原始文件
  (不做 canvas 转码,保留动画);上传前按 10 MiB 做大小判断(服务端仍
  按平台策略强制校验);把上传+预览+导航头像更新逻辑抽为
  uploadAvatarBytes(blob, filename),裁剪流与 GIF 直传共用
- 服务端(UploadAvatar):GIF(配置 MIME=image/gif,已过白名单/魔数校验)
  跳过 256x256 缩放与 JPEG 重编码,原字节直存,files 行
  ext=.gif / mime=image/gif;其他类型行为不变
- 新增 TestAvatarUploadGifStoredRaw:原始字节一致性/哈希命名/
  files 行元数据/归属者断言
You are not authorized to merge this pull request.
This pull request can be merged automatically.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u https://git.lmve.net/dsh/go_blog feat/avatar-gif:dsh-feat/avatar-gif
git checkout dsh-feat/avatar-gif
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kevin/go_blog#11