const handleDownLoad =(filename: string)=>{
const url = `${dataDownLoad.url}?filename=${filename}.xlsx`;
fetch(url, {
method: 'GET',
// body: JSON.stringify({ filename }), //fetch get请求不可以包含body!!
credentials: 'include',
headers: new Headers({
'Content-Type': 'application/json'
}),
}).then((response) => {
response.blob().then(blob => {
const aLink = document.createElement('a');
document.body.appendChild(aLink);
aLink.style.display='none';
aLink.href = window.URL.createObjectURL(blob);
aLink.download = filename+'.xlsx';
aLink.click();
document.body.removeChild(aLink);
});
}).catch((error) => {
console.log(error);
});
}
注意:
-
在fetch中,请求类型为'GET'时,不可以带body参数
-
response.blob()是一个异步操作,因为返回的是一个完整的二进制数据,流式传输不能一次传完,所以blob返回的是一个promise。blob() 方法采用Response流并将其读入完成。它返回一个与 Blob 一起解决的promise。
-
生成的a标签要添加download属性,在不加download属性的时候,a标签点击之后,浏览器下载的文件名乱码且打开文件失败,显示“xxx的文件格式和扩展名不匹配,文件可能已经损坏或不安全”。添加了download属性之后,a标签点击之后,浏览器会强制进行文件下载,下载的文件名称就是download所命名的文件名,这里要带后缀。
扩展内容:
fetch基于Promise设计,在ES6中出现,是原生js,没有使用XMLHttpRequest对象。详细内容见:fetch官方文档
使用注意:fetch只对网络请求报错,对400,500都当做成功的请求,可以在第一个.then回调函数中,response.json().then()回调中拿到后端返回值,再作判断。这里response.json()是一个Promise,所以只能访问一次。一个文件上传的fetch请求栗子:
fetch(url, {
method: 'POST',
body: formData
}).then(response => {
// console.log(response.json()); //response.json()是一个Promise,只可以访问一次,.then()返回请求得到的数据
response.json().then((res: any) => {
if(res.code === 200) {
message.success('文件上传成功,'+res.msg);
} else {
message.error('文件上传失败,'+res.msg);
}
})
}).catch(() => {
message.error('文件上传失败');
}).finally(() => {
loadDataList();
setUploadModalVisible(false);
form.resetFields();
});
主要优势:
1.语法简洁,更加语义化
2.基于标准 Promise 实现,支持 async/await
3.同构方便
4.更加底层,提供的API丰富(request, response)
5.脱离了XHR,是ES规范里新的实现方式
与ajax区别:
1.ajax是理用XMLHttpRequest对象来请求数据的,而fetch是window的一个方法
2.ajax基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
3.fetch比较与ajax有着更好更方便的写法
4.fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
5.fetch没有办法原生监测请求的进度,而XHR可以