fetch本身不直接提供上传进度事件,但可通过xhr原生实现upload.onprogress监听,或用fetch+分块上传/readablestream(实验性)模拟;推荐优先使用兼容性好、标准稳定的xmlhttprequest方案。

fetch 本身不直接提供上传进度事件,但可以通过 ReadableStream + TransformStream 或更实际的方式 —— 手动构造请求体并配合 ProgressEvent 模拟监听。不过要注意:原生 fetch 的 body 是只读流,无法直接监听上传过程;真正可行且兼容性好的方案是使用 XMLHttpRequest(XHR),或借助 fetch + Blob.slice + 自定义分块上传 实现近似效果。
用 XMLHttpRequest 实现精确上传进度监听(推荐)
尽管问题问的是 fetch,但 XHR 是目前唯一能原生触发 upload.onprogress 的标准方式,兼容所有现代浏览器,代码清晰、可控性强:
- 创建
XMLHttpRequest实例,监听xhr.upload.onprogress - 使用
FormData构造请求体(支持文件、字段混合上传) - 调用
xhr.send(formData)发起请求
示例:
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const percent = (e.loaded / e.total) * 100;
console.log(`上传中:${percent.toFixed(2)}%`);
}
};
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status console.error('上传失败');
<p>const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'my-file');
xhr.open('POST', '/upload');
xhr.send(formData);
</p>fetch + 分块上传模拟进度(需后端配合)
若必须用 fetch,可将大文件切片(如每 64KB 一块),逐块上传,并累加已上传字节数。这种方式需要后端支持「分片接收+合并」逻辑(如 tus 协议或自定义接口):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
file.slice(start, end)获取 Blob 子段 - 每次 fetch 前更新进度变量,手动计算百分比
- 注意处理并发、断点续传、顺序合并等细节
适合对上传可靠性要求高、文件超大的场景,但开发成本明显高于 XHR。
fetch + ReadableStream(实验性,兼容性差)
Chrome 120+ 支持通过 new Request(url, { body: stream }) 传入可读流,并在流 pipe 过程中插入进度统计逻辑(例如用 TransformStream 包装原始 Blob 流):
- 创建
TransformStream,在transform()中累计已读字节数并派发自定义事件 - 将文件 Blob 转为流:
file.stream(),再通过pipeThrough()注入进度逻辑 - 当前仅 Chromium 系支持,Firefox/Safari 尚未实现
file.stream(),不建议生产环境使用
小结:选型建议
日常开发中,上传进度监听应优先选择 XMLHttpRequest —— 它稳定、标准、无需 polyfill,且 API 简洁。fetch 更适合无进度要求的简单请求或响应式下载(可用 response.body.getReader() 监听下载进度)。强行用 fetch 做上传进度,往往得不偿失。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










