前端发展至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的实现方案。
- 原生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字符串>'); //发送请求,如果是异步请求,那么该方法将在请求发送后立即返回。
}
- 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/…