首页 > 其他分享 >使用 Axios 下载文件并更新进度条

使用 Axios 下载文件并更新进度条

时间:2024-08-14 18:48:44浏览次数:5  
标签:Axios const 进度条 axios link file percentage 下载

使用 Axios 下载文件并更新进度条

使用axiosonDownloadProgress回调函数实现下载文件,并更新下载进度条。

示例代码

import { ElMessage } from "element-plus";
import axios from "axios";
import type { AxiosResponse, AxiosProgressEvent } from "axios";
import { baseUrl } from "@/utils/baseUrl";
import type { FileInfo } from "@/interfaces";

const apiPrefix = "/api-file";

type ProgressCallback = (file: FileInfo, progress: number) => void;

// 防抖函数
function debounce<ProgressCallback extends (...args: any) => any>(
  func: ProgressCallback,
  wait: number
): ProgressCallback {
  let startTime = Date.now();
  return function (this: any, ...args: Parameters<ProgressCallback>) {
    if (Date.now() - wait >= startTime) {
      func.apply(this, args);
      startTime = Date.now();
    }
  } as ProgressCallback;
}

export async function downloadFile(
  file: FileInfo,
  token: string | null,
  updateProgressBar: ProgressCallback
): Promise<void> {
  try {
    const updateProgress = debounce(updateProgressBar, 500); // 500ms 防抖间隔时间
    const response: AxiosResponse = await axios({
      url: `${baseUrl}${apiPrefix}/files/${file.id}/`,
      method: "GET",
      responseType: "blob", // 接收二进制数据
      headers: token ? { Authorization: "Bearer " + token } : {},
      onDownloadProgress: (progressEvent: AxiosProgressEvent) => {
        const total = progressEvent.total;
        const current = progressEvent.loaded;
        if (total) {
          const percentage = Math.floor((current / total) * 100);
          updateProgress(file, percentage);
        }
      },
    });

    if (response.headers["content-type"].startsWith("application/json")) {
      const resCode = response.data.code;
      if (resCode !== 0) {
        ElMessage.warning(response.data.msg);
      }
    } else {
      // 处理文件名,从响应头的 content-disposition 中获取
      let filename = "";
      const disposition = response.headers["content-disposition"];
      const disposition = response.headers["content-disposition"];
      if (disposition) {
        const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
        const matches = filenameRegex.exec(disposition);
        if (matches && matches[1]) {
          filename = matches[1].replace(/['"]/g, ""); // 去除引号
        }
      }
      // 处理下载的文件
      const urlBlob = window.URL.createObjectURL(new Blob([response.data]));
      const link = document.createElement("a");
      link.style.display = "none";
      link.href = urlBlob;
      link.download = filename; // 指定下载后的文件名,防止跳转
      document.body.appendChild(link);
      link.click();
      window.URL.revokeObjectURL(urlBlob);
      document.body.removeChild(link);
    }
  } catch (error) {
    console.error("Error downloading the file:", error);
    ElMessage.warning("下载文件失败,请稍后再试");
  }
}

/**
 * 更新页面中的进度条
 */
const updateProgressBar = (file: FileInfo, percentage: number) => {
  file.downloading = true;
  console.log(`Download progress: ${percentage}%`);
  file.downloadingProgress = percentage;
};

代码讲解

1. 使用 axios 进行文件下载

使用axios发送了一个GET请求来下载文件,并指定了responseTypeblob,以确保接收到的文件是二进制数据,并在请求头中传入 jwt token。

const response: AxiosResponse = await axios({
  url: `${baseUrl}${apiPrefix}/files/${file.id}/`,
  method: "GET",
  responseType: "blob", // 接收二进制数据
  headers: token ? { Authorization: "Bearer " + token } : {},
});

2. 实现下载进度的更新

通过axiosonDownloadProgress回调函数,可以获取下载的进度。回调函数在文件下载过程中不断触发,提供了loadedtotal两个属性,分别代表已下载的字节数和总字节数。

onDownloadProgress: (progressEvent: AxiosProgressEvent) => {
  const total = progressEvent.total;
  const current = progressEvent.loaded;
  if (total) {
    const percentage = Math.floor((current / total) * 100);
    updateProgress(file, percentage);
  }
};

为了防止进度条更新过于频繁导致的性能问题,使用了一个简单的防抖函数debounce,将更新进度的频率限制为 500 毫秒。
调用downloadFile函数时,需要传入updateProgressBar函数,在该函数中实现更新页面进度条操作。

/**
 * 更新页面中的进度条
 */
const updateProgressBar = (file: FileInfo, percentage: number) => {
  file.downloading = true;
  console.log(`Download progress: ${percentage}%`);
  file.downloadingProgress = percentage;
};

3. 文件处理与下载

在下载完成后,根据响应头中的Content-Disposition获取文件名,然后创建了一个 URL 对象,并利用a标签触发文件下载。

const urlBlob = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement("a");
link.style.display = "none";
link.href = urlBlob;
link.download = filename; // 指定下载后的文件名,防止跳转
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(urlBlob);
document.body.removeChild(link);

标签:Axios,const,进度条,axios,link,file,percentage,下载
From: https://www.cnblogs.com/shouwangrenjian/p/18359586

相关文章

  • 根据网络连接(文件链接)下载文件到本地
    1publicvoidDownloadFile(stringURL,stringfilename)2{3HttpWebRequestreq=null;4HttpWebResponserep=null;5Streamst=null;6Streamso=null;7try8{9req=(HttpWebRequest)Web......
  • 图片批量加水印软件下载
    最近经常做图片,而且还需要加水印,之前用的图片加水印工具是只能一张图片一张图片的加,有很多图片的话处理起来就比较浪费时间,然后在网上找了一个能批量加水印的软件,感觉挺好用的,和大家分享一下,还有以前用的单张图片加水印工具一同分享了。进入正题:1、单张图片加水印工具这是......
  • IntelliJ IDEA【最新】2024终极版 下载安装教程,图文步骤详解
    文章目录软件介绍软件下载安装步骤ActivationMethod专栏推荐:超多精品软件(持续更新中…)软件介绍IntelliJIDEA是一款由JetBrains公司开发的集成开发环境(IDE),专为软件开发人员设计,尤其在Java编程领域享有极高的声誉,被认为是市场上最好的JavaIDE之一。以下是对In......
  • Cisco Secure Firewall 4200 Series FTD Software 7.4.2 & ASA Software 9.20.3 发布
    CiscoSecureFirewall4200SeriesFTDSoftware7.4.2&ASASoftware9.20.3发布下载-思科防火墙系统软件FirepowerThreatDefense(FTD)Software请访问原文链接:https://sysin.org/blog/cisco-firepower-4200/,查看最新版。原创作品,转载请保留出处。为什么选择CiscoSe......
  • Cisco Secure Firewall 3100 Series FTD Software 7.4.2 & ASA Software 9.20.3 发布
    CiscoSecureFirewall3100SeriesFTDSoftware7.4.2&ASASoftware9.20.3发布下载-思科防火墙系统软件FirepowerThreatDefense(FTD)Software请访问原文链接:CiscoSecureFirewall3100SeriesFTDSoftware7.4.2&ASASoftware9.20.3,查看最新版。原创作品,转载请......
  • Cisco Firepower 9300 Series FTD Software 7.4.2 & ASA Software 9.20.3 发布下载 -
    CiscoFirepower9300SeriesFTDSoftware7.4.2&ASASoftware9.20.3发布下载-思科防火墙系统软件FirepowerThreatDefense(FTD)Software请访问原文链接:https://sysin.org/blog/cisco-firepower-9300/,查看最新版。原创作品,转载请保留出处。为什么选择CiscoSecure......
  • maven仓库下载不下来的包如何自己安装(本地宝导入到maven仓库)
    1.下载jar包https://mvnrepository.com/在官网上搜索jar包,点击下载2.将jar包放在一个没有中文的路径下(我放在了D盘根路径下)打开CMD框执行下面的命令mvninstall:install-file-Dfile=D:\kingbase8-8.6.0.jar-DgroupId=com.kingbase-DartifactId=kingbase8-Dversion=8......
  • Civitai模型的一个下载技巧
    简介Civitai网站本身是无法直连的,但是Civitai的下载API用的是Cloudflare的服务,是可以直连的。因此,只要能够获取模型的下载链接,就可以在任意环境中直连下载模型了。操作流程本文以https://civitai.com/models/639120这个模型为例,说明操作流程。本文假设读者使用的是Ch......
  • CH340一键下载电路
    单片机串口一键下载方案一、概述CH340X/N/K/CH343/CH342等USB转串口芯片可实现不同类型MCU串口一键下载功能,对于支持多模式启动的STM32Fxxx/CH32Fxxx/CH32Vxxx等系列、ESP系列等MCU,使用CH340X、CH343和CH342芯片时无需外围三极管等逻辑控制电路,将芯片提供的输出信号脚直连M......
  • Python搭建一个下载服务器
    一、Python2搭建一个下载服务器 1、查看是python2环境 2、执行 python-mSimpleHTTPServer 3、阿里云放开8000安全组4、直接查看路径   二、Python3搭建一个下载服务器cd/homepython3-mhttp.server 下载页面 ......