前端点击下载:

72 阅读2分钟

最近项目中遇到了不同的点击下载的场景,后台表格点击下载excel文件以及点击下载zip压缩包文件

分别对几种场景的点击下载进行一个总结:

a标签

查看mdn对于a标签下载的描述:

image.png

let url = "xxxx.zip"
`<a href={url} download>点我下载</a>`

blob文本文件下载

  const exportHandle = () => {
    setExportLoading(true);
    const request = extend({
      timeout: 50000,
      // 处理http请求错误 未处理业务错误 业务错误baseRequest中处理
      errorHandler: httpErrorHandler,
      credentials: 'include', // 默认请求是否带上cookie
    });
    request('you_url', {
      method: 'get',
      responseType: 'blob',
      getResponse: true,
    })
      .then(({ data, response }) => {
        //  实例读取文件对象
        const r = new FileReader();
        r.onload = function () {
          try {
            // this.result为FileReader获取blob数据,如果返回报错信息,则是正确的json数据,JSON.parse会正常转换
            //  如果返回文件流,则JSON.parse时会报错,走catch代码块(进行正常的文件下载)
            const resData = JSON.parse(this.result as string);
            //  resData是后端返回的json数据
            if (resData.code === -1) {
              message.error(resData.msg || '导出错误');
              return;
            }
          } catch (error) {
            downLoad(data, response);
          }
        };
        r.readAsText(data);
      })
      .catch((error) => {
        console.log(error);
        message.error('导出错误');
      })
      .finally(() => {
        setTimeout(() => {
          setExportLoading(false);
        }, 1000);
      });
  };

json无法解析,说明返回的是blob文件,此时,catch到download中执行逻辑

// 下载
const downLoad = (data: BlobPart, response: Response) => {
  let blob = new Blob([data], { type: 'application/zip' });
  // 获取 获取响应头 heads 中的 filename 文件名
  const filename = response.headers.get('content-disposition');
  let changeFileName = '';
  if (filename) {
     // 解析文件名
    changeFileName = decodeURI(filename.split('=')[1]);
    changeFileName = decodeURIComponent(changeFileName.substring(filename.indexOf(' ')));
  }
  let fileName = changeFileName || '数据.zip';
  //  创建一个 a 标签
  const link = document.createElement('a');
  //  不显示a标签
  link.style.display = 'none';
  // 给a 标签的href属性赋值
  link.href = URL.createObjectURL(blob);
  link.setAttribute('download', fileName);
  //  把a标签插入页面中
  document.body.appendChild(link);
  link.click();
  // 点击之后移除a标签
  document.body.removeChild(link);
};

URL.createObjectURL() 是 JavaScript 中的一个方法,属于 URL 构造函数的一部分。这个方法的作用是创建一个临时的、唯一的、以 blob: 协议开头的URL,这个URL可以用来表示一个 Blob 对象或 File 对象。

当你调用 URL.createObjectURL() 并传入一个 BlobFile 对象时,它会返回一个表示该对象的URL。这个URL可以用于任何需要URL的地方,比如在 <img> 标签的 src 属性中设置图片源,在 <a> 标签的 href 属性中设置下载链接,或者在 <script> 标签的 src 属性中加载一个JavaScript文件。

图片下载

// 加载的图片对象
function(img, filename){
  let a = document.createElement("a");
  let canvas = document.createElement('canvas');
  let context = canvas.getContext('2d');
  let width = domImg.naturalWidth;
  let height = domImg.naturalHeight;
  context.drawImage(img, 0, 0);
  a.href = canvas.toDataURL('image/jpeg');
  //a.href = canvas.toDataURL('image/png'); ...
  a.download = filename;
  a.style.display = "none";
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
  document.body.removeChild(a);
}

function downloadImage(blob, filename) {
  // 创建Blob对象
  const imageBlob = new Blob([blob], { type: 'image/png' });
  
  // 创建临时URL
  const imageUrl = URL.createObjectURL(imageBlob);
  
  // 创建下载链接
  const link = document.createElement('a');
  link.href = imageUrl;
  link.download = filename || 'download.png';
  link.style.display = 'none'; // 避免显示在页面上
  document.body.appendChild(link);
  
  // 触发下载
  link.click();
  
  // 清理
  document.body.removeChild(link);
  URL.revokeObjectURL(imageUrl);
}

// 假设你有一个包含图片数据的ArrayBuffer
const imageArrayBuffer = ...;

// 调用函数下载图片
downloadImage(imageArrayBuffer);