fetch API 本身不直接支持请求进度的监控,但你可以通过使用 ReadableStream 和 Response.body 来间接实现下载进度的跟踪。对于上传进度,fetch 目前没有直接的方法来跟踪。
( D$ a8 X$ j4 N7 o8 U/ w以下是一个使用 fetch 和 ReadableStream 来获取下载进度的示例:( Q5 |+ @/ F5 H/ u# a8 r8 X
function fetchWithProgress(url, onProgress) {
return fetch(url).then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const contentLength = response.headers.get('Content-Length');
if (!contentLength) {
console.warn('Content-Length response header is missing');
}
const total = parseInt(contentLength, 10);
let loaded = 0;
const reader = response.body.getReader();
const stream = new ReadableStream({
start(controller) {
function read() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
loaded += value.length;
if (onProgress) {
onProgress(loaded, total);
}
controller.enqueue(value);
read();
}).catch(error => {
console.error('Stream reading error:', error);
controller.error(error);
});
}
read();
}
});
return new Response(stream, { headers: response.headers });
});
}
// 使用示例
fetchWithProgress('https://example.com/large-file.zip', (loaded, total) => {
console.log(`Progress: ${loaded} / ${total}`);
}).then(response => {
return response.blob();
}).then(blob => {
// 处理下载的 blob
}).catch(error => {
console.error('Fetch error:', error);
}); 在这个示例中,我们使用 ReadableStream 来读取响应流,并在每次读取时更新进度。onProgress 回调函数会被调用,并传入已加载的字节数和总字节数(如果可用)。这种方法适用于监控下载进度,但对于上传进度,你可能需要使用 XMLHttpRequest。
' i- c( ~( O5 W* O( [ @8 rfunction uploadFile(file) {
const xhr = new XMLHttpRequest();
// 监听上传进度事件
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
console.log(`Upload progress: ${percentComplete.toFixed(2)}%`);
}
});
// 监听下载进度事件
xhr.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
console.log(`Download progress: ${percentComplete.toFixed(2)}%`);
}
});
// 请求完成时的事件
xhr.addEventListener('load', () => {
if (xhr.status === 200) {
console.log('Upload complete!');
} else {
console.error('Upload failed!');
}
});
// 请求错误时的事件
xhr.addEventListener('error', () => {
console.error('Request error!');
});
// 设置请求方法和目标URL
xhr.open('POST', 'your-upload-url-here');
// 发送请求
xhr.send(file);
}
// 使用示例
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (file) {
uploadFile(file);
}
}); ReadableStream3 @% ~" C/ B2 h: L3 w' r
Stream API 中的 ReadableStream 接口表示可读的字节数据流。Fetch API 通过 Response 的属性 body 提供了一个具体的 ReadableStream 对象。 |