fetch api流式下载大文件需通过response.body获取readablestream分块读取,避免使用response.json()等缓冲方法以防内存溢出;结合abortcontroller控制请求、实时计算进度并妥善处理错误与取消。

Fetch API 支持流式下载大文件,关键在于不等待整个响应体加载完成,而是通过 response.body 获取可读流(ReadableStream),逐块读取并写入磁盘或进度条更新。核心是避免调用 response.json()、response.text() 或 response.blob() —— 这些方法会缓冲全部内容到内存,对大文件极易导致内存溢出。
1. 使用 ReadableStream 分块读取响应体
从 fetch() 得到的 Response 对象中提取 body,用 getReader() 创建流读取器,循环调用 read() 获取 { done, value } 块(value 是 Uint8Array):
- 每次
read()返回一个 chunk,适合控制内存占用(例如限制单次处理 ≤64KB) - 需手动处理
done === true表示流结束 - 注意:
body只能被消费一次,不可重复读取
2. 边下载边写入文件(浏览器端)
在浏览器中,无法直接写入本地文件系统,但可通过 WritableStream 配合 createWriteStream(Node.js)或使用 @#@#@#@#@#@#@#@#@#@0(现代浏览器)。更通用的做法是:构建 Blob 并触发下载,同时用 TransformStream 实时累积数据并更新进度:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 创建
new WritableStream({ write: chunk => { /* 存入数组或计算进度 */ } }) - 或用
new Response(response.body).blob()不推荐——仍会缓冲全量 - 推荐组合:
response.body.pipeTo(writable)+new WritableStream自定义写入逻辑
3. 实时计算下载进度
利用 response.headers.get('content-length') 获取总大小(服务端需设置 Content-Length 或启用 Transfer-Encoding: chunked 并配合其他方式估算):
- 若响应头含
Content-Length,可精确计算百分比:(loaded / total) * 100 - 若为分块传输且无总长,只能显示“正在接收数据…”或基于已接收字节数做相对进度(如每 1MB 触发一次回调)
- 注意:某些代理或服务器可能不返回
Content-Length,需做好降级处理
4. 错误处理与取消下载
流式下载需主动监听网络中断、用户中止等异常:
- 用
AbortController控制请求生命周期:fetch(url, { signal }) - 读取流时捕获
reader.read()的 rejected promise(如网络错误、流中断) - 调用
reader.cancel()清理资源,避免内存泄漏 - 下载中途取消时,确保释放已分配的
Uint8Array和关闭WritableStream
不复杂但容易忽略:流式下载不是“自动优化”,必须显式处理流、控制 chunk 大小、监听终止信号,并兼顾兼容性(如 File System Access API 尚未全平台支持)。实际项目中常配合 Service Worker 缓存或后台下载任务提升体验。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










