当前位置:首页 > 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 tab实现

vue tab实现

Vue Tab 实现方法 使用动态组件实现 Tab 在 Vue 中可以通过动态组件 <component :is="currentTab"> 结合 v-for 和 v-bind 实现 Ta…

vue监听实现

vue监听实现

Vue 监听实现方法 在 Vue 中可以通过多种方式实现监听数据变化或事件触发,以下是常见的几种方法: 使用 watch 选项 watch 是 Vue 提供的核心功能之一,用于观察和响应 Vue 实…

vue实现pc

vue实现pc

Vue 实现 PC 端应用开发 Vue.js 是一个流行的前端框架,适用于构建 PC 端 Web 应用。以下是关键步骤和最佳实践: 项目初始化 使用 Vue CLI 或 Vite 创建项目:…

vue 轮询实现

vue 轮询实现

轮询的基本概念 轮询是一种通过定时向服务器发送请求来获取最新数据的技术。适用于需要实时更新但无法使用WebSocket的场景。 使用setInterval实现轮询 在Vue组件中,可以通过setIn…

vue实现侧导航

vue实现侧导航

Vue 实现侧边导航 使用 Vue 实现侧边导航可以通过多种方式完成,以下是一种常见的实现方法,结合 Vue Router 和动态组件。 基础结构 创建侧边导航栏的基本结构,通常使用 <ul&…

vue  全局刷新实现

vue 全局刷新实现

全局刷新实现方法 在Vue中实现全局刷新通常涉及重新加载整个应用或特定路由。以下是几种常见方法: 使用window.location.reload() 强制浏览器重新加载当前页面: window.…