正确使用 Blob 导出文件需严格匹配 type 与内容编码,如 text/csv;charset=utf-8;必须用 a.download + URL.createObjectURL() 触发下载,并在 finally 中调用 URL.revokeObjectURL();new File() 需传数组且 lastModified 为毫秒数;大文件应分片处理。

直接用 Blob 构造数据、配合 URL.createObjectURL() 触发下载,是前端生成并导出文件最轻量且兼容性最好的方式;但错填 type、漏调 URL.revokeObjectURL()、或把 Blob 当 File 直接传给 FormData,都会导致下载失败、预览空白、上传丢名等实际问题。
怎么用 Blob 正确构造文本/JSON/Excel 文件
构造 Blob 的核心不是“有没有数据”,而是“类型声明是否匹配内容编码”。字符串直接传进去没问题,但必须显式指定 type 并带上 charset,否则中文会乱码或浏览器解析失败:
-
text/plain或text/csv必须写成"text/plain;charset=utf-8",不能只写"text/plain" -
application/json同理,要写"application/json;charset=utf-8",否则某些环境(如旧版 Edge)解析 JSON 时会报错 - 前端生成 Excel(如用 SheetJS),
Blob的type必须是"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",写成"application/octet-stream"可能导致双击打不开 - 不要传空
type:new Blob([data])得到的blob.type === "",在<img>或<iframe>中大概率不渲染
为什么 download 属性 + createObjectURL 是唯一稳方案
用 location.href = URL.createObjectURL(blob) 看似简单,但在 Safari 和多数 iOS WebView 中会打开空白页,且无法控制文件名;而 <a download> 组合是目前所有现代浏览器(IE10+、Chrome、Firefox、Safari 10.1+)都稳定支持的下载路径:
- 必须设置
a.download属性,否则点击后可能跳转而非下载 - 必须调用
a.click(),仅设href不触发任何行为 -
download属性在非同源页面(如data:协议)下会被忽略,此时浏览器自动命名为unknown - 生成的 URL 是内存引用,不是真实地址,不能用于
fetch或跨域请求
Blob 转 File 为什么总报错:Failed to construct 'File'
new File() 构造函数对参数格式极其严格,常见错误都是因为没按规范传参:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
立即学习“前端免费学习笔记(深入)”;
- 第一个参数必须是数组,哪怕只有一个元素:
new File([blob], 'name.png', {type: blob.type})✅,new File(blob, 'name.png')❌(报parameter 1 is not of type 'sequence') -
lastModified必须是毫秒时间戳(number),不是Date实例,传错会导致该字段被忽略 - 从
canvas.toBlob()拿到的Blob是异步回调里的,别在 Promise 外直接用,否则blob是undefined - 传给
FormData.append('file', file)才能带filename字段;若传Blob,后端收到的是无名 body,multer、Django等框架会报 “missing filename”
大文件处理最容易被忽略的三件事
超过 50MB 的 Blob 构造和下载,真正卡住的往往不是网络,而是内存管理和生命周期控制:
-
new Blob([hugeArray])会一次性拷贝全部数据,极易 OOM;应改用Blob.slice()分片 +ReadableStream流式处理(Chrome/Firefox 支持,Safari 仍受限) -
URL.createObjectURL()后必须配对调用URL.revokeObjectURL(),但很多人只在下载成功后清理,却没覆盖用户取消、网络中断、脚本异常等场景 —— 建议统一用try/finally包裹 - 反复对同一
Blob调用createObjectURL()会产生多个 URL,但底层共享同一份内存;revoke其中任意一个,其余 URL 全部失效 —— 别靠多次创建来“保险”
真正难的不是写出能跑通的代码,而是判断什么时候不该用 Blob:比如需要持久化存储、跨 Tab 共享、或做文件系统级操作时,它根本不是解决方案。

















