其他分享
首页 > 其他分享> > 文件下载

文件下载

作者:互联网

文件下载

  1. 下载接口返回 File 文件
  2. 下载接口返回 base64 字符串

下载接口返回 File 文件

location.href 下载

这种下载请求方式不会被 axios 拦截进行统一处理,相当于直接在浏览器地址栏访问,不会携带 token。因此需要在后端给接口配置白名单才能被访问

/**
 * http://127.0.0.1/download 是下载接口地址
*/
downloadFile(){
    window.location.href = 'http://127.0.0.1/download'
}

利用 a 标签 的 href 属性下载文件

    downloadFile() {
      console.log("文件下载");
      this.$axios({
        url: "/download",
        method: "get",
        // responseType: "ArrayBuffer", // 文件下载 默认格式 ArrayBuffer
        responseType: "blob", // 设置拿到的响应数据的格式
      }).then((res) => {
        console.log(res.data);
        const blob = res.data;
        let url = URL.createObjectURL(blob);
        console.log(url);
        let link = document.createElement("a");
        link.href = url;
        link.download = "img.jpg";
        link.style.visibility = "hidden";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });
    },

下载接口返回 base64 字符串

base64 文件,利用 a 标签下载

base64 文件转 blob,blob 转 ObjectUrl,利用 a 标签下载

/**
 * content 为文件的 base64 码,
 * fileName 为下载到系统的文件名
*/
downloadFile(fileName, base64Url) {
    // base64转blob
    function base64ToBlob(code) {
      const parts = code.split(';base64,');
      const contentType = parts[0].split(':')[1];   // 获取文件类型
      const raw = window.atob(parts[1]);
      const rawLength = raw.length;
      const uInt8Array = new Uint8Array(rawLength);
      for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
      }
      return new Blob([uInt8Array], { type: contentType });
    }
    const blob = this.base64ToBlob(base64Url);

    if (window.navigator.msSaveOrOpenBlob) { // 判断客户端是否允许直接下载blob,有msSaveOrOpenBlob方法表示允许下载,此方法ie适用
        navigator.msSaveBlob(blob, fileName);
    }
    else {  // 客户端不允许下载,需要借用a标签的href属性下载文件
        const link = document.createElement('a');   // 创建a标签
        link.href = window.URL.createObjectURL(blob); // 指定下载的内容 URL.createObjectURL(blob)将blob转为本地url
        link.download = fileName;   // 指定默认文件名
        //此写法兼容可火狐浏览器
        // 在Chrome浏览器下,模拟点击创建的<a>元素即使不append到页面中,也是可以触发下载的,但是在Firefox浏览器中却不行,因此,上面的funDownload()方法有一个appendChild和removeChild的处理,就是为了兼容Firefox浏览器。
        document.body.appendChild(link);    // 挂载a标签
        const evt = document.createEvent("MouseEvents");    // 创建鼠标事件
        evt.initEvent("click", false, false);   // 初始化鼠标事件 为单击事件 阻止冒泡 阻止默认事件
        link.dispatchEvent(evt);    // 触发evt事件
        document.body.removeChild(link);    // 移除节点
    }
},

下普通文本文件,利用 a 标签下载

/**
 * content 指需要下载的文本或字符串内容,
 * filename 指下载到系统中的文件名称
 */
let downloadFile = function (content, filename) {
  // 创建隐藏的可下载链接
  let eleLink = document.createElement('a')
  eleLink.download = filename
  eleLink.style.display = 'none'
  // 字符内容转变成blob地址
  let blob = new Blob([content])
  eleLink.href = URL.createObjectURL(blob)
  // 触发点击
  document.body.appendChild(eleLink)
  eleLink.click()
  // 然后移除
  document.body.removeChild(eleLink)
}

使用 canvas 下载页面上展示的图片

domImg 为下载的 img DOM 节点,fileName 为下载到系统的文件名

let downloadFile = function (domImg, filename) {
  // 创建隐藏的可下载链接
  let eleLink = document.createElement('a')
  eleLink.download = filename
  eleLink.style.display = 'none'
  // 图片转base64地址
  let canvas = document.createElement('canvas')
  let context = canvas.getContext('2d')
  let width = domImg.natureWidth
  let height = domImg.natureHeight
  context.drawImage(domImg, 0, 0)
  // 如果是PNG图片,则context.toDataURL('image/png')
  eleLink.href = context.toDataURL('image/jpeg')
  // 触发点击
  document.body.appendChild(eleLink)
  eleLink.click()
  // 然后移除
  document.body.removeChild(eleLink)
}

ie9 及以上 base64 文件下载

downloadFile(){
  // 判断是否为ie浏览器
  if(!!window.ActiveXObject || "ActiveXObject" in window){
      // 是ie浏览器
      this.downloadFileForIE(url,fileName)
  }else{
      // 是标准浏览器
      // ......
  }
  downloadFileForIE(url,fileName){
      let blobStr = window.atob(url,split(',')[1])  // atob() 方法用于解码使用 base-64 编码的字符串 为blob字符串
      let n = blobStr.length
      let u8arr = new Uint8Array(n) // Uint8Array数组表示一个8位无符号整数数组,数组长度为n
      while(n--){
          u8arr[n]=blobStr.charCodeAt(n)   // charCodeAt()将字符转换为Unicode编码
      }
      let blob = new Blob([u8arr])  // 将字符数组 转为blob字符串
      window.navigator.msSaveOrOpenBlob(blob,imgName) //下载或打开blob文件,下载到系统的文件名为imgName
  }
}

实战演练

Vue + express 实现文件下载

前端

<el-button type="primary" @click="download">项目笔记下载</el-button>
    download() {
      console.log("文件下载");
      this.$axios({
        url: "/download",
        method: "get",
        // responseType: "ArrayBuffer", // 文件下载 默认格式 ArrayBuffer
        responseType: "blob", // 设置拿到的响应数据的格式
      }).then((res) => {
        console.log(res.data);
        const blob = res.data;
        let url = URL.createObjectURL(blob);
        console.log(url);
        let link = document.createElement("a");
        link.href = url;
        link.download = "img.jpg";
        link.style.visibility = "hidden";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });
    },

后端

exports.download = (req, res) => {
  res.download('./public/img/aaa-1648172747193.webp')
}

标签:文件,eleLink,let,blob,link,document,下载
来源: https://www.cnblogs.com/guoyanchao/p/16054827.html