利用流式传输优化大型文件上传的核心思路是通过实时传输避免浏览器缓存整个文件,从而降低内存消耗并防止卡顿。 具体实现方法如下:
1. 采用Fetch API实现流式传输2. 分块传输与流式写入结合- 分块处理:若需进一步优化,可将文件分块后逐块上传(需服务端支持分块接收)。
- 流式写入:通过ReadableStream和WritableStream管道连接,实现数据边读取边写入:async function uploadFile(file) { const fileStream = file.stream(); // 获取文件流 const response = await fetch('/upload', { method: 'POST', body: fileStream, // 直接传递文件流 }); return response;}
3. 兼容性与限制处理4. 服务端配合优化- 支持流式接收:服务端需能处理持续的数据流(如Node.js的pipeline或Nginx的流式代理)。
- 示例(Node.js):const express = require('express');const app = express();app.post('/upload', (req, res) => { const writable = getWritableStream(); // 获取可写流 req.pipe(writable); // 直接管道传输});
5. 用户体验增强- 进度反馈:通过ReadableStream的tee()方法复制流,一份用于上传,一份用于计算进度:const [originalStream, progressStream] = file.stream().tee();// 监听progressStream计算进度fetch('/upload', { body: originalStream });
- 错误处理:捕获流式传输中的错误(如网络中断),支持断点续传。
6. 替代方案(兼容性场景)- 传统分块上传:将文件切分为多个块,逐块上传并合并(需服务端支持)。
- WebSocket流式传输:适用于需要双向通信的场景,但复杂度较高。
总结- 核心方案:优先使用Fetch API的流式传输,结合duplex: 'half'实现半双工通信。
- 关键检查点:
浏览器兼容性(Safari需回退)。
服务端HTTP/2支持。
错误处理与进度反馈。
- 扩展建议:参考
Chrome开发者文档
(需替换为实际链接)深入底层实现。
通过以上方法,可有效解决大型文件上传时的浏览器卡顿问题,同时兼顾兼容性与用户体验。