Skip to content

[cloud] fix: 云盘 PDF 预览链路修复 + 侧边目录增强 (#92) - #93

Merged
atoncooper merged 4 commits into
mainfrom
fix/cloud-drive-pdf-preview
Aug 30, 2026
Merged

[cloud] fix: 云盘 PDF 预览链路修复 + 侧边目录增强 (#92)#93
atoncooper merged 4 commits into
mainfrom
fix/cloud-drive-pdf-preview

Conversation

@atoncooper

Copy link
Copy Markdown
Owner

Closes #92

改动总览(4 commits,按模块拆分)

1. [frontend] PDF 同源代理 + 新标签页原生预览

  • frontendv2/next.config.ts:新增 /minio-proxy/:path* beforeFiles rewrite(Next 服务端转发 nginx→MinIO),生产模式(NEXT_PUBLIC_API_URL 设值)也保留;rewrites 在构建时固化进 routes-manifest,destination 必须走 build argMINIO_PROXY_DEST,运行时 env 无效——本次踩坑实证)。
  • frontendv2/components/cloud-drive/file-viewer.tsx:presigned URL 归一化为同源相对路径(带 /minio-proxy/ 前缀时),PDF 改为 window.open 新标签页交给浏览器原生查看器(带弹窗拦截兜底卡片 + 下载链接),video/audio/image 不变。
  • frontendv2/Dockerfile:npm registry 切 npmmirror(musl swc 二进制不在 Windows 锁文件,next build 现场下载直连必断);healthcheck 改 wget 127.0.0.1(busybox localhost→IPv6 vs Next 只绑 IPv4,unhealthy 误报根因)。

2. [backend] presign 注入真实 MIME + 构建加固

  • app/infra/minio.pypresigned_get 支持 response_headers(签名进 query)。
  • app/routers/cloud.py/raw 对 pdf/video/audio/image 注入 response-content-type=file.mime_type——解决 octet-stream+nosniff 拒嗅探,对存量对象同样生效
  • Dockerfile:FROM digest 固定(buildkit 联网解析 tag 国内反复失败,digest 离线命中本地镜像);pip --timeout 120 --retries 5(默认 15s 清华源大包必超时)。

3. [docker] compose 传 MINIO_PROXY_DEST build arg

4. [frontend] 侧边目录增强

  • 任意层级新建子文件夹(hover +,内嵌输入框);
  • 重命名(PATCH /cloud/folders/{id} 前端首次接线);
  • 展开/折叠状态持久化 localStorage;
  • 选中深层文件夹自动展开祖先链 + scrollIntoView;
  • 无文件夹空状态。

验证

  • tsc --noEmit + next build 通过
  • 同一 presigned URL:直连 nginx 200;经 :3000 同源代理 200 + Content-Type: application/pdf(211KB PDF 完整)
  • 容器内 SDK 签名 + GET 实测 MIME 注入生效
  • 侧边目录新代码已确认在容器产物中,页面 200
  • 本地 Docker Desktop 全栈手工回归:上传→入库→预览→新标签页原生渲染

影响范围

  • 不触碰 chat/RAG/session 链路;/raw 响应结构不变(仅 URL 查询串多签名参数)
  • 兼容自定义 MINIO__PUBLIC_ENDPOINT(非 /minio-proxy 路径时前端保持绝对 URL 不改写)

- next.config: /minio-proxy/* beforeFiles rewrite(Next 服务端转发 nginx→MinIO),
  生产模式(NEXT_PUBLIC_API_URL 设值)也保留;MINIO_PROXY_DEST 走 build arg
  (rewrites 在构建时固化进 routes-manifest,运行时 env 无效)
- file-viewer: presigned URL 归一化为同源相对路径,PDF 用 window.open 新标签页
  交给浏览器原生查看器(原 iframe 会被 nginx X-Frame-Options SAMEORIGIN 跨源拒绝)
- Dockerfile: npm registry 切 npmmirror(musl 平台 swc 二进制不在 Windows 锁文件
  里,next build 现场下载直连 npmjs 必断);healthcheck wget 改 127.0.0.1(busybox
  localhost 解析 IPv6,Next 只绑 IPv4,容器永远 unhealthy)
- minio.presigned_get 支持 response_headers(签名进 query);raw 端点对
  pdf/video/audio/image 注入 response-content-type=file.mime_type——对象存储为
  octet-stream 且链路带 nosniff 时浏览器拒绝嗅探,iframe/媒体元素无法渲染;
  对存量对象同样生效
- Dockerfile: FROM 按 digest 固定(buildkit 每次联网解析 tag 在国内网络下反复
  失败,digest 可离线命中本地镜像);pip 加 --timeout 120 --retries 5
  (默认 15s,清华源下大包传输停顿即整层失败)
rewrites destination 构建时固化,MinIO 同源代理目标必须作为 build arg 传入
(http://nginx:80,走 compose 内网),运行时 environment 不生效
- hover 操作组:新建子文件夹(任意层级,内嵌输入框)/ 重命名(PATCH
  /folders/{id} 前端首次接线)/ 删除(沿用确认弹窗)
- 展开/折叠状态提升到侧栏并持久化 localStorage(原来刷新后强制全展开)
- 选中深层文件夹时自动展开祖先链并 scrollIntoView(含 localStorage 恢复的
  上次位置)
- 无文件夹空状态提示
@atoncooper
atoncooper merged commit 7c53f5d into main Aug 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[cloud] fix: 云盘 PDF 无法预览(XFO 跨源拒绝 iframe + MIME octet-stream 拒嗅探)

1 participant