blob是浏览器内存中的二进制数据容器,无文件路径和真实元信息;file是其子类,含name等属性且来自用户选择或显式构造,能被formdata识别为上传文件。

HTML 中的 Blob 是什么,和本地文件有什么本质区别
Blob 不是文件,而是浏览器内存中的一段二进制数据容器。它没有路径、没有文件系统元信息(比如 lastModified 是只读模拟值)、也不能直接被 fs.readFile 读取——Node.js 根本不认识它。而 File 是 Blob 的子类,额外携带了 name、lastModified 和 webkitRelativePath 等属性,通常来自 <input type="file"> 或拖拽事件。
关键区别在于:Blob 可以由 JS 动态生成(比如 new Blob([JSON.stringify(obj)], {type: 'application/json'})),File 则必须来自用户主动选择或 API 显式构造(如 new File([blob], 'a.txt', {type: 'text/plain'}))。
- File 对象能被 FormData.append 正确识别为“上传文件”,Blob 会当作普通二进制字段(服务端收到的是无名 body,不是 multipart/form-data 中的 file 字段)
- 调用
URL.createObjectURL(file)和URL.createObjectURL(blob)都能生成可访问的 URL,但只有 File 的 URL 在 Chrome DevTools 的 Network 面板里会显示原始文件名 - FileList 是只读类数组,不能 push 或 splice;Blob 则完全可控,可拼接、切片、转 ArrayBuffer
用 URL.createObjectURL 预览 Blob 时为什么点开是空白或报错
常见错误是忽略 MIME type 或类型不匹配。浏览器根据 Blob 的 type 字段决定如何解析内容,而不是靠文件扩展名。比如把 JSON 字符串塞进 new Blob([str], {type: 'text/html'}),再用 <iframe src="blob:xxx"></iframe> 加载,就会因 HTML 解析失败而空白。
- 图片预览必须用准确类型:
image/png、image/jpeg,不能写成image/jpg(IE/Edge 旧版除外) - 文本类内容推荐用
text/plain;charset=utf-8,避免中文乱码;HTML 内容必须用text/html,且确保字符串本身是合法 HTML - 调用
URL.createObjectURL后记得在不用时调用URL.revokeObjectURL(url),否则内存泄漏(尤其在频繁生成预览的列表页) - 不要对同一个 Blob 多次调用
createObjectURL,返回的 URL 不同,但底层引用同一份内存,revoke 任意一个都会使全部失效
从 Blob 获取真实文件名的几种可行方式
Blob 本身没有名字。如果你看到某段代码里 blob.name 存在,那它其实是个 File 对象(或被手动挂了 name 属性),不是原生 Blob。
- 用户选择的文件:直接从
input.files[0].name或event.target.files[0].name拿,别试图从后续生成的 Blob 倒推 - 后端返回的 Blob:检查响应头
Content-Disposition,例如attachment; filename="report.pdf",可用正则提取:filename="([^"]+)" - 自己构造的 Blob:用
new File([blob], 'default.txt', {type: blob.type})包一层,获得带 name 的 File 实例 - 注意:Safari 对
Content-Disposition解析较弱,建议后端同时在响应头设置X-File-Name自定义字段作 fallback
把 Blob 传给后端时,fetch 和 FormData 该怎么选
取决于后端接口要求。如果后端明确接收 multipart/form-data(比如 Express 的 multer、Django 的 request.FILES),必须用 FormData;如果接受原始二进制 body(如 req.body 流式读取),直接传 Blob 更轻量。
- 用 FormData:
const fd = new FormData(); fd.append('file', blob, 'upload.pdf');—— 第三个参数是文件名,会出现在Content-Disposition里 - 直接 fetch:
fetch('/upload', {method: 'POST', body: blob})—— 此时请求体就是纯二进制,Content-Type自动设为 blob.type,后端需按 raw body 处理 - 常见坑:误把 Blob 当字符串传,比如
body: JSON.stringify({file: blob}),结果传过去的是[object Blob]字符串 - 大文件上传建议加
AbortController控制中断,Blob 本身不支持 cancel,但 fetch 请求可以
真正容易被忽略的是:Blob 的 type 字段只是提示,不校验内容。一张伪造的 PNG 文件头被塞进 type: 'text/plain' 的 Blob,浏览器仍会按 text/plain 渲染——服务端做 MIME 类型校验时,得靠文件头(magic bytes)而非请求头判断。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











