应用笔记 · 2023年5月31日

前端使用axios实现文件下载功能

在前后端分离开发的项目中,前端无论使用Vue或React哪种框架,发送HTTP请求都会使用Ajax异步请求的方式。在很多项目中都会选择使用 axios 发送请求。但是在使用 axios 实现下载功能时,往往会出现以下问题。

当前端直接使用 axios 去请求下载文件的 api 接口时,状态码返回200,但是获取的数据却是一堆乱码,效果如下:

2、问题分析

下载其实是浏览器的内置事件,浏览器的 GET请求(frame、a)、 POST请求(form)具有如下特点:

  • response 会交由浏览器处理;
  • response 内容可以为二进制文件、字符串等。

但是AJAX请求不一样:

  • response 会交由 Javascript 处理;
  • response 内容只能接收字符串才能继续处理。

因此,AJAX本身无法触发浏览器的下载功能。

3、解决方案

要在 axios 的 config 配置 responseType: ‘blob’ (非常关键),服务端读取文件,以 content-type: ‘application/octet-stream’ 的格式返回前端,前端接收到数据后使用 Blob 来接收数据,并且创建a标签进行下载。

一个对象的类型取决于 responseType 的值,当值为 “blob”时表示 response 是一个包含二进制数据的 Blob 对象。
在使用 axios 发起请求前,首先了解一下 responseType 这个属性是如何在 axios 中使用的。以 axios 最常用的 get 和 post 请求为例,这两种请求方式在传递参数的时候也是不同的:
在get请求当中,config 是第二个参数,而到了 post 里 config 变成了第三个参数,这是传递 responseType 第一个需要注意的地方。

4、代码实现

后端实现以 express 为例:

 

前端在使用 axios 请求下载文件 api 接口时,一定要区分不同请求方法的使用,语法如下:

 

前端解析数据流,主要使用 Blob 对象来进行接收,示例代码如下:

 

后台返回的流文件是一张图片的话,前端需要将这张图片直接展示出来,例如登录时的图片验证码,示例代码如下: