vue大文件下载实现
分片下载实现大文件下载
使用axios配合Blob对象实现分片下载,避免一次性加载大文件导致内存溢出。通过设置responseType: 'blob'和Range请求头实现分片:
async function downloadLargeFile(url, fileName, chunkSize = 1024 * 1024 * 10) {
const fileBlob = new Blob();
let startByte = 0;
let endByte = chunkSize - 1;
while (true) {
const response = await axios.get(url, {
headers: { 'Range': `bytes=${startByte}-${endByte}` },
responseType: 'blob'
});
const receivedBytes = response.data.size;
if (receivedBytes === 0) break;
fileBlob = new Blob([fileBlob, response.data]);
startByte = endByte + 1;
endByte = startByte + chunkSize - 1;
}
const downloadUrl = URL.createObjectURL(fileBlob);
const a = document.createElement('a');
a.href = downloadUrl;
a.download = fileName;
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(downloadUrl);
a.remove();
}
使用StreamSaver.js实现流式下载
对于超大文件(GB级别),推荐使用StreamSaver.js库实现真正的流式下载,避免内存占用问题:

import streamSaver from 'streamsaver';
async function streamDownload(url, fileName) {
const fileStream = streamSaver.createWriteStream(fileName);
const response = await fetch(url);
const readableStream = response.body;
if (window.WritableStream && readableStream.pipeTo) {
return readableStream.pipeTo(fileStream);
}
const writer = fileStream.getWriter();
const reader = response.body.getReader();
const pump = () => reader.read()
.then(res => res.done
? writer.close()
: writer.write(res.value).then(pump));
return pump();
}
进度显示与中断控制
添加下载进度显示和中断控制功能,提升用户体验:

let controller = new AbortController();
async function downloadWithProgress(url, fileName) {
const response = await fetch(url, {
signal: controller.signal
});
const totalBytes = +response.headers.get('Content-Length');
let receivedBytes = 0;
const chunks = [];
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
receivedBytes += value.length;
const progress = (receivedBytes / totalBytes * 100).toFixed(2);
console.log(`Downloaded ${progress}%`);
}
const blob = new Blob(chunks);
// ...保存逻辑同前
}
// 中断下载
function abortDownload() {
controller.abort();
}
服务端配合要求
服务端需要支持以下特性才能实现完整的大文件下载功能:
- 支持
Range请求头(HTTP 206 Partial Content) - 正确返回
Content-Length头信息 - 对于分片下载需支持
Accept-Ranges: bytes头 - 若使用CORS需配置
Access-Control-Expose-Headers: Content-Length, Content-Range
断点续传实现
通过本地存储记录已下载的字节位置,实现断点续传功能:
function resumeDownload(url, fileName) {
const savedProgress = localStorage.getItem(`dl_${fileName}`);
let startByte = savedProgress ? parseInt(savedProgress) : 0;
// 修改Range头
const headers = { 'Range': `bytes=${startByte}-` };
// 在每次收到数据时更新存储
const updateProgress = (received) => {
localStorage.setItem(`dl_${fileName}`, startByte + received);
};
}






