[Bug] Web 端同步导出(PPTX/PDF/图片)常被浏览器静默拦截:window.open 在 await 之后已脱离用户手势
Author: zgybkjcn-a11yCreated Sep 12, 2026Updated Sep 12, 2026
Deployment Method / 部署方式
Docker Compose (docker-compose.yml) — Web 模式(非桌面客户端)
Issue Description / 问题描述
frontend/src/api/client.ts 的 triggerDownload Web 分支用 window.open(url, '_blank') 触发下载。
同步导出路径(PPTX / PDF / 图片)是先 await apiExportPPTX(...)(后端生成需要十几秒),再调 triggerDownload(downloadUrl)。等生成完成时,点击按钮产生的 transient user activation 早已过期,window.open 被浏览器弹窗拦截器静默拦截 —— 用户看到「点导出没反应」,控制台只有一行 popup blocked 警告。
可编辑 PPTX 走后台任务轮询,下载是从任务面板的用户点击触发的,不受影响;受影响的是三条同步导出路径(SlidePreview.tsx L1686 附近调用)。
Steps to Reproduce / 复现步骤
- Web 模式打开(非桌面客户端)
- 导出 → PPTX(同步路径,后端生成耗时 > 5 秒)
- 生成完成后没有弹出下载
Expected Behavior / 期望行为
生成完成后直接触发浏览器下载,不被弹窗拦截器拦截。
建议修复
用隐藏 <a download> 替代 window.open(不受弹窗拦截限制、不依赖 activation 新鲜度,也不会把大文件在新标签页里打开):
const link = document.createElement('a');
link.href = url;
link.rel = 'noopener';
link.download = filename; // 跨源时 download 被忽略、退回默认导航,仍优于被拦截
document.body.appendChild(link);
link.click();
link.remove();包一层 try/catch,失败时回退现有 window.open。已开 PR,见下方链接。
Version / 版本
v0.9.0-rc.7 与 main (199cf9e) 均存在
Source: Anionex/banana-slides