您可以使用 JavaScript 的 ReadableStream
来实现带有下载进度的响应。下面是一个示例代码,演示了如何使用 fetch
函数和 ReadableStream
来获取文件并显示下载进度:
// 获取文件的下载进度
function getDownloadProgress(response, onProgress) {
const contentLength = response.headers.get('content-length');
let receivedBytes = 0;
return new Response(
new ReadableStream({
start(controller) {
const reader = response.body.getReader();
function read() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
receivedBytes += value.byteLength;
onProgress(receivedBytes, contentLength);
controller.enqueue(value);
read();
});
}
read();
}
})
);
}
// 下载文件
function downloadFile(url, onProgress) {
fetch(url).then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return getDownloadProgress(response, onProgress);
}).then(downloadResponse => {
const disposition = response.headers.get('content-disposition');
const filenameMatch = disposition.match(/filename="([^"]+)"/);
const filename = filenameMatch && filenameMatch[1] ? filenameMatch[1] : 'download.file';
const blob = downloadResponse.blob();
// 将文件下载到本地
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
URL.revokeObjectURL(link.href);
}).catch(error => {
console.error(error);
});
}
// 在页面上显示下载进度
function updateProgress(receivedBytes, contentLength) {
const progressPercent = (receivedBytes / contentLength * 100).toFixed(2);
console.log(`Downloaded ${progressPercent}%`);
}
// 开始下载文件
downloadFile('https://example.com/somefile.pdf', updateProgress);
在上面的代码中,getDownloadProgress
函数使用 Response
和 ReadableStream
来创建一个新的响应对象,该对象在每次读取文件内容时更新下载进度。在 downloadFile
函数中,获取文件的响应会被传递给 getDownloadProgress
,并开始读取内容。然后,将包含文件内容的响应保存为 blob
,并使用 a
标签的 download
属性下载文件到本地。
updateProgress
函数用于在页面上显示下载的进度,可以根据自己的需要进行修改。
请注意,ReadableStream
是一项实验性功能,在某些浏览器中可能不受支持。如果需要兼容性,请考虑使用其他方法来实现下载进度的功能。