[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.tstriggerDownload 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 / 复现步骤

  1. Web 模式打开(非桌面客户端)
  2. 导出 → PPTX(同步路径,后端生成耗时 > 5 秒)
  3. 生成完成后没有弹出下载

Expected Behavior / 期望行为

生成完成后直接触发浏览器下载,不被弹窗拦截器拦截。

建议修复

用隐藏 <a download> 替代 window.open(不受弹窗拦截限制、不依赖 activation 新鲜度,也不会把大文件在新标签页里打开):

typescript
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) 均存在