Antd:实现文件下载

2,499 阅读2分钟
  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);
    });
  }

注意:

  1. 在fetch中,请求类型为'GET'时,不可以带body参数

  2. response.blob()是一个异步操作,因为返回的是一个完整的二进制数据,流式传输不能一次传完,所以blob返回的是一个promise。blob() 方法采用Response流并将其读入完成。它返回一个与 Blob 一起解决的promise。

  3. 生成的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可以