angular 使用blob二进制流的方式下载后台文件

先说两个比较古老的js下载方式,

1. window.open(src)和window.location = src

2. form表单提交

这两个方式都有局限性,对于需要传递大量参数的下载请求,可以这样写:

this.http.post(`${this.uri}/exportdata.file`, params, {responseType: 'blob'}).subscribe(data => {
  const link = document.createElement('a');
  const blob = new Blob([data], {type: 'application/zip'});
  link.setAttribute('href', window.URL.createObjectURL(blob));
  link.setAttribute('download', new Date().getTime() + '.zip');
  link.style.visibility = 'hidden';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
})

这里通过设置 responseType: 'blob' 获取了文件的二进制流,再通过a标签的方式模拟点击下载。

这种下载方式有两点需要注意:

1. 下载的文件格式需要确定

上面的例子下载的是zip格式,如果是其他格式,需要改变Content-Type(代码第三行) 以及 文件名后缀(第五行)。比如:

 'doc'        => 'application/msword',

 'xls'        => 'application/vnd.ms-excel',

2. 文件名是前端命名还是后端命名

前端命名的话上面的代码就可以了,如果需要后端命名,首先需要后端在响应头中带上文件名,比如:

Content-disposition: attachment; filename=file_201807201030327711.zip

再对上面的post请求做一下修改:

this.http.post(`${this.uri}/exportdata.file`, params, {responseType: 'blob', observe: 'response'}).subscribe(data => {
  const link = document.createElement('a');
  const blob = new Blob([data.body], {type: 'application/zip'});
  link.setAttribute('href', window.URL.createObjectURL(blob));
  link.setAttribute('download', data.headers.get('Content-disposition').split('filename=')[1]);
  link.style.visibility = 'hidden';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
})

通过设置 observe: 'response' 获取到返回的响应头,再获取其中的文件名。

你可能感兴趣的:(ng)