ImageViewer 默认导出通过 blob 下载跨域图片(DES-133)
版本: 0.4.1 · 类型: 🐛 Bug Fix
问题
未传入 onExport prop 时,ImageViewer 的默认导出使用 <a download> + 原始 src URL。然而 download 属性仅对同源、blob: 或 data: URL 生效。实际场景中大多数图片来自跨域 CDN,浏览器出于安全限制会静默忽略跨域资源的 download 属性,转而直接导航到该 URL——导致"导出时打开了新标签页"而非触发下载。设计站使用的 picsum.photos(跨域)稳定复现了该问题。
改动文件
src/components/ImageViewer/ImageViewer.tsxsrc/components/ImageViewer/__tests__/ImageViewer.test.tsxsrc/components/ImageViewer/ImageViewerDesignSpec.mdpackages/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 非 2xx(
response.ok为 false)时,回退到原始 URL——确保不会静默失败,也避免将错误页内容保存为损坏的图片文件。 - objectURL 撤销延迟 1000 ms(
OBJECT_URL_REVOKE_DELAY),在下载触发后执行,防止同步revokeObjectURL在浏览器读取 blob 前就释放对象。 - 下载文件名从
src最后一段路径推断;无有效名称时回退到浏览器默认文件名。 - 新增模块级辅助函数:
getFileNameFromSrc/triggerAnchorDownload/downloadImageBySrc。 - 组件 JSDoc 及
onExportprop 注释已更新,反映 blob 下载行为。
ImageViewer.test.tsx 中的测试
- 原"回退锚点下载"测试用例改写为 blob 下载断言(mock
fetch/URL.createObjectURL/revokeObjectURL;验证 fetch 参数、锚点点击及延迟 objectURL 撤销)。 - 新增测试:fetch 失败时回退到直接原始 URL 下载。
- 新增测试:HTTP 非 2xx(404)回退——验证不创建 objectURL 且下载直接使用原始 URL。
文档
ImageViewerDesignSpec.md 与 image-viewer.mdx 的导出说明已更新,反映 blob 下载方案。