利用a标签携带token实现下载并完美兼容IE!!!

作为一名前端开发者,我们经常遇到下载文件的场景(包括:图片,文档,压缩包等),解决办法五花八门,而且使用场景过于单一...

常规方法

常规方法我们会用a标签或者form表单来实现下载功能。

  • a 标签

a标签的用法都很熟悉,但是却有两个致命缺点:

  1. 不能携带鉴权信息 token

  2. 兼容性问题

image

只有 火狐和谷歌浏览器支持!!!

  • form 表单

form 表单用法很早就有,但是有个明显的缺点:不能修改文件名称

那么需要一个能携带token信息且能修改文件名称还要兼容各大浏览器 怎么结局这个问题呢?本文将为你带来一种 能携带token信息且能修改文件名称还要兼容各大浏览器 的方法!

一生二 二生三 三生万物

核心利于XMLHttpRequesta标签来解决携带 token 信息,利用微软自带的msSaveBlob 方法来兼容IE浏览器

首先能携带token信息

 var xhr = new XMLHttpRequest();
 xhr.open('GET', url, true);
 //设置请求头参数的方式,如果没有可忽略此行代码
 xhr.setRequestHeader("Authorization",`Bearer ${idToken}`));
 //设置响应类型为 blob   xhr.open必须为 异步
 xhr.responseType = 'blob';
 //关键部分
 xhr.onload = function (e) {
    //如果请求执行成功
    if (this.status == 200) {
      let blob = this.response;
      let a = document.createElement('a');
      // blob.type = "application/octet-stream";
      let url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = decodeURIComponent(xhr.getResponseHeader("content-disposition").split(";")[1].split("filename=")[1]);
        document.body.appendChild(a); // 火狐浏览器 必须把元素插入body中
        a.click();
        document.body.removeChild(a);
        //释放之前创建的URL对象
        window.URL.revokeObjectURL(url);
    }
}

然后解决兼容IE浏览器 问题并完善异常捕获

  var xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  // xhr.open('POST', url, true);  // post 请求
  // xhr.setRequestHeader("content-type", 'application/json'); // post请求携带body体参数,需要设置此行
  //设置请求头参数的方式,如果没有可忽略此行代码
  xhr.setRequestHeader("Authorization",`Bearer ${idToken}`));
  //设置响应类型为 blob
  xhr.responseType = 'blob';
  // 关键部分
  xhr.onload = function (e) {
    // 如果请求执行成功
    if (this.status == 200) {
      let blob = this.response
      let a = document.createElement('a')
      // blob.type = "application/octet-stream";
      let url = window.URL.createObjectURL(blob)
      let fileName = decodeURIComponent(escape(xhr.getResponseHeader('content-disposition').split(';')[1].split('filename=')[1]))
      if (window.navigator.msSaveBlob) {
        try {
          window.navigator.msSaveBlob(blob, fileName)
        } catch (e) {
          console.log(e)
        }
      } else {
        a.href = url
        a.download = fileName
        document.body.appendChild(a) // 火狐浏览器 必须把元素插入body中
        a.click()
        document.body.removeChild(a)
        // 释放之前创建的URL对象
        window.URL.revokeObjectURL(url)
      }
    } else { // 失败后需要将blob对象转换为 json 来获取异常信息
      const reader = new FileReader();
      reader.readAsText(this.response, 'utf-8');
      reader.onload = () => {
        const { header } = JSON.parse(reader.result);
        console.error(header.msg)
      }
    }
  }
  xhr.send()
  // xhr.send(JSON.stringify({ id, orgNo, keyWord }))  // 将携带参数转化为 JSON

更多前端相关文章:January丶缘 或者 haoys.xyz

你可能感兴趣的:(利用a标签携带token实现下载并完美兼容IE!!!)