前端文件处理与浏览器存储机制实践
🎯 一、文件处理为何重要?
现代 Web 应用中文件处理场景非常广泛:
- 上传头像/简历/Excel 等文件
- 图片压缩、预览、转码(Base64、Blob)
- 大文件切片上传与断点续传
- 读取本地文件内容(如 .csv、.xlsx)
- 下载文件并自动命名
这些场景都考验前端对浏览器 File API、Blob、FormData、Storage API 等底层能力的掌握。
🧠 二、浏览器文件处理 API 一览
API | 作用 |
---|---|
File |
文件对象(通常来源于 <input type="file"> ) |
FileReader |
读取文件内容为文本、URL、ArrayBuffer |
Blob |
二进制数据对象,常用于生成文件下载 |
FormData |
构建带文件的 multipart/form-data 请求 |
URL.createObjectURL() |
创建 blob 链接用于图片预览、下载等 |
📂 三、文件上传:获取 + 预览 + 上传流程
1️⃣ 获取文件对象
html
<input type="file" id="fileInput" />
js
const input = document.getElementById('fileInput');
input.addEventListener('change', (e) => {
const file = e.target.files[0];
console.log('文件名:', file.name);
});
2️⃣ 图片预览:使用 Blob URL
js
const imgUrl = URL.createObjectURL(file);
document.getElementById('preview').src = imgUrl;
✅ 别忘了销毁 URL,避免内存泄漏:
js
URL.revokeObjectURL(imgUrl);
3️⃣ 上传文件:使用 FormData
js
const formData = new FormData();
formData.append('file', file);
fetch('/api/upload', {
method: 'POST',
body: formData
});
✂️ 四、大文件分片上传 + 秒传机制
📦 为什么要切片上传?
- 避免大文件拖慢上传速度甚至失败
- 支持断点续传、重试机制
- 支持秒传(MD5 检测已有文件)
🧩 分片核心思路:
js
const chunkSize = 1 * 1024 * 1024; // 1MB
const file = input.files[0];
const chunks = [];
for (let i = 0; i < file.size; i += chunkSize) {
chunks.push(file.slice(i, i + chunkSize));
}
每一片上传时携带 fileId + chunkIndex
,后端完成后再合并切片。
📤 五、浏览器文件下载机制(Blob 下载)
js
const blob = new Blob(['Hello world'], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'hello.txt';
a.click();
URL.revokeObjectURL(url);
✅ 可下载后端返回的二进制流(如 Excel、PDF 等):
js
fetch('/api/export')
.then(res => res.blob())
.then(blob => {
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'report.xlsx';
link.click();
});
🗃 六、浏览器本地存储机制对比
存储方式 | 容量限制 | 特点 | 应用场景 |
---|---|---|---|
localStorage |
~5MB | 同源永久存储,页面刷新不丢失 | 保存用户设置、登录状态 |
sessionStorage |
~5MB | 同源 + 同窗口,关闭即失效 | 临时状态保存(如表单草稿) |
IndexedDB |
上限为硬盘容量 | 支持对象存储、索引、事务 | 本地缓存海量数据、离线图书馆 |
cookie |
~4KB | 每次请求自动带上,支持跨域设置 | 会话状态、权限管理 |
🛠 七、存储常见技巧
✅ 本地存储封装工具
ts
const Storage = {
get(key: string) {
try {
return JSON.parse(localStorage.getItem(key) || '');
} catch {
return null;
}
},
set(key: string, value: any) {
localStorage.setItem(key, JSON.stringify(value));
},
remove(key: string) {
localStorage.removeItem(key);
}
};
🧪 八、面试高频问题拆解
📌 Q1:文件上传为什么要用 FormData?可以用 JSON 吗?
答:FormData 支持构建 multipart/form-data
类型请求,适用于文件上传。而 JSON 无法直接包含 File
或二进制数据,需手动处理转码和边界,效率低下。
📌 Q2:如何实现大文件分片上传与断点续传?
答:
- 使用
slice()
方法按固定大小分片; - 每一片上传携带标识(fileId, chunkIndex);
- 后端提供合并接口;
- 可将已上传片段记录到本地/IndexedDB 以支持断点续传。
📌 Q3:localStorage 和 IndexedDB 区别?
对比点 | localStorage | IndexedDB |
---|---|---|
数据结构 | 键值对(字符串) | 支持对象、索引、事务控制 |
容量 | 几 MB | GB 级别 |
异步 | 否 | 是(支持 Promise 接口) |
应用 | 简单用户设置、缓存小内容 | 离线缓存系统、图片、文件、日志 |
✅ 总结
技术点 | 关键要素 |
---|---|
文件处理 | 获取 File、预览 Blob、读取 FileReader |
大文件上传 | 切片 + 合并 + 秒传识别(MD5) |
本地存储 | localStorage / session / IndexedDB |
文件下载 | Blob + URL.createObjectURL |
掌握这些底层浏览器 API 的应用,不仅能提升你的业务实现能力,也是在面试中体现"基础扎实 + 能解决真实问题"的重要体现。