当前位置:首页 > VUE

vue大文件下载实现

2026-01-21 05:10:53VUE

分片下载实现大文件下载

使用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库实现真正的流式下载,避免内存占用问题:

vue大文件下载实现

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();
}

进度显示与中断控制

添加下载进度显示和中断控制功能,提升用户体验:

vue大文件下载实现

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);
  };
}

标签: 大文件vue
分享给朋友:

相关文章

vue实现生成二维码

vue实现生成二维码

使用qrcode.vue库生成二维码 安装qrcode.vue库: npm install qrcode.vue --save 在Vue组件中使用: <template> <…

vue实现后退

vue实现后退

Vue 实现后退功能的方法 在 Vue 中实现后退功能通常可以通过以下几种方式完成,具体取决于应用场景和需求。 使用 window.history API 通过原生 JavaScript 的 win…

vue插槽实现

vue插槽实现

插槽的基本概念 Vue插槽(Slot)是一种内容分发机制,允许父组件向子组件传递模板片段,子组件通过<slot>标签定义接收位置。插槽的核心作用是增强组件的灵活性和复用性。 默认插槽 子…

vue实现异步

vue实现异步

Vue 实现异步操作的常见方法 Vue 提供了多种方式来处理异步操作,包括数据获取、事件处理等场景。 使用 async/await 在 Vue 方法中可以直接使用 async/await 语法处理异…

vue轮询实现

vue轮询实现

Vue 轮询实现方法 在 Vue 中实现轮询可以通过以下几种方式: 使用 setInterval data() { return { pollInterval: null }…

vue 实现打印

vue 实现打印

Vue 实现打印功能的方法 在Vue项目中实现打印功能,可以通过以下几种方式实现: 使用window.print()方法 通过调用浏览器的原生打印API实现基础打印功能,适用于简单内容打印。 //…