跳到主要内容

ImageViewer 默认导出通过 blob 下载跨域图片(DES-133)

版本: 0.4.1 · 类型: 🐛 Bug Fix

DES-133DES-129 的子任务)

问题

未传入 onExport prop 时,ImageViewer 的默认导出使用 <a download> + 原始 src URL。然而 download 属性仅对同源、blob:data: URL 生效。实际场景中大多数图片来自跨域 CDN,浏览器出于安全限制会静默忽略跨域资源的 download 属性,转而直接导航到该 URL——导致"导出时打开了新标签页"而非触发下载。设计站使用的 picsum.photos(跨域)稳定复现了该问题。

改动文件

  • src/components/ImageViewer/ImageViewer.tsx
  • src/components/ImageViewer/__tests__/ImageViewer.test.tsx
  • src/components/ImageViewer/ImageViewerDesignSpec.md
  • packages/design-site/docs/components/patterns/image-viewer.mdx

改动内容

ImageViewer.tsx 中的 blob 下载

默认导出改为:fetch(src)blob()URL.createObjectURL,生成同源 objectURL 后触发 <a download>。跨域 CDN 图片现在可以真正下载(要求 CDN 返回正确的 CORS 响应头)。

  • 当 fetch 失败(CORS 拒绝 / 网络错误)或 HTTP 非 2xxresponse.ok 为 false)时,回退到原始 URL——确保不会静默失败,也避免将错误页内容保存为损坏的图片文件。
  • objectURL 撤销延迟 1000 ms(OBJECT_URL_REVOKE_DELAY),在下载触发后执行,防止同步 revokeObjectURL 在浏览器读取 blob 前就释放对象。
  • 下载文件名从 src 最后一段路径推断;无有效名称时回退到浏览器默认文件名。
  • 新增模块级辅助函数:getFileNameFromSrc / triggerAnchorDownload / downloadImageBySrc
  • 组件 JSDoc 及 onExport prop 注释已更新,反映 blob 下载行为。

ImageViewer.test.tsx 中的测试

  • 原"回退锚点下载"测试用例改写为 blob 下载断言(mock fetch / URL.createObjectURL / revokeObjectURL;验证 fetch 参数、锚点点击及延迟 objectURL 撤销)。
  • 新增测试:fetch 失败时回退到直接原始 URL 下载。
  • 新增测试:HTTP 非 2xx(404)回退——验证不创建 objectURL 且下载直接使用原始 URL。

文档

ImageViewerDesignSpec.mdimage-viewer.mdx 的导出说明已更新,反映 blob 下载方案。