前端文件下载之POST请求下载

1,526 阅读1分钟

前端发展至0202年,文件下载已经是老生常谈的需求。最常见的实现方式莫过于基于get请求的a标签点击下载。

<a href="http://url?xxx=xxx" download="xxx.xx">文件下载</a>

get请求实现下载的优点很明显,简单快捷,只需后台提供url即可。但是缺点也很致命,主流浏览器对请求的URL限制最大长度,需要传递很多参数给后端时就显得极为苍白。

GET请求URL长度限制:www.cnblogs.com/cyl048/p/11…

所以如果有需要传递大量参数时,还是要考虑基于post请求的解决方案。本文总结了基于原生XMLHttpRequest和热门请求库axios的实现方案。

  1. 原生xhr下载
const xhr = new XMLHttpRequest();
xhr.open('post',url,true); //参数解释:[请求类型,请求地址,是否异步]
xhr.responseType = 'blob'; //指定返回类型,post下载的关键点
req.setRequestHeader('Content-Type', 'xxx'); //指定请求头类型
xhr.onload = () => {
  if( xhr.status === 200 ){
    const blob = xhr.response;
    if( blob && blob.size > 0 ){
      const stream = new Blob([blob]);
      const downloadUrl = window.URL.createObjectURL(stream);
      const a = document.createElement('a');
      a.href = downloadUrl;
      a.click()
      window.URL.revokeObjectURL(downloadUrl); //释放内存
    }
  };
 xhr.send('<请求参数:json字符串>'); //发送请求,如果是异步请求,那么该方法将在请求发送后立即返回。
}
  1. axios下载
import axios from 'axios';

axios({
  method:'post',
  headers:{
    'Content-Type':xxx
  },
  responseType:'blob', //post下载的关键点
}).then(res => {
  if( res ){
    const blob = res.data;
    if( blob && blob.size > 0 ){
      const stream = new Blob([blob]);
      const downloadUrl = window.URL.createObjectURL(stream);
      const a = document.createElement('a');
      a.href = downloadUrl;
      a.click()
      window.URL.revokeObjectURL(downloadUrl); //释放内存
    }
  }
})

总结:post下载的关键点是在请求时指定responseType为blob类型,如果未指定responseType为blob类型,打印返回的response,可以看到流文件被转成了字符串,转成blob对象下载的文件会报错无法打开。 指定类型后,打印返回的response如下,流文件被转成由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array,可以正常下载打开啦~

MDN-Blob() :developer.mozilla.org/zh-CN/docs/…

MDN-URL.createObjectURL() :developer.mozilla.org/zh-CN/docs/…