前端下载二进制流文件

简介: 前端下载二进制流文件

平时在前端下载文件有两种方式,一种是后台提供一个 URL,然后用 window.open(URL) 下载,另一种就是后台直接返回文件的二进制内容,然后前端转化一下再下载。

由于第一种方式比较简单,在此不做探讨。本文主要讲解一下第二种方式怎么实现。

Blob、ajax(axios)

mdn 上是这样介绍 Blob 的:

Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据

具体使用方法

axios({
  method: 'post',
  url: '/export',
})
.then(res => {
  // 假设 data 是返回来的二进制数据
  const data = res.data
  const url = window.URL.createObjectURL(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}))
  const link = document.createElement('a')
  link.style.display = 'none'
  link.href = url
  link.setAttribute('download', 'excel.xlsx')
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
})

打开下载的文件,看看结果是否正确。

一堆乱码...

一定有哪里不对。

最后发现是参数 responseType 的问题,responseType 它表示服务器响应的数据类型,由于后台返回来的是二进制数据,所以我们要把它设为 arraybuffer

接下来再看看结果是否正确。

axios({
  method: 'post',
  url: '/export',
  responseType: 'arraybuffer',
})
.then(res => {
  // 假设 data 是返回来的二进制数据
  const data = res.data
  const url = window.URL.createObjectURL(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}))
  const link = document.createElement('a')
  link.style.display = 'none'
  link.href = url
  link.setAttribute('download', 'excel.xlsx')
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
})

这次没有问题,文件能正常打开,内容也是正常的,不再是乱码。

根据后台接口内容决定是否下载文件

作者的项目有大量的页面都有下载文件的需求,而且这个需求还有点变态。

具体需求如下

  1. 如果下载文件的数据量条数符合要求,正常下载(每个页面限制下载数据量是不一样的,所以不能在前端写死)。
  2. 如果文件过大,后台返回 { code: 199999, msg: '文件过大,请重新设置查询项', data: null },然后前端再进行报错提示。

先来分析一下,首先根据上文,我们都知道下载文件的接口响应数据类型为 arraybuffer。返回的数据无论是二进制文件,还是 JSON 字符串,前端接收到的其实都是 arraybuffer。所以我们要对 arraybuffer 的内容作个判断,在接收到数据时将它转换为字符串,判断是否有 code: 199999。如果有,则报错提示,如果没有,则是正常文件,下载即可。具体实现如下:

axios.interceptors.response.use(response => {
    const res = response.data
    // 判断响应数据类型是否 ArrayBuffer,true 则是下载文件接口,false 则是正常接口
    if (res instanceof ArrayBuffer) {
        const utf8decoder = new TextDecoder()
        const u8arr = new Uint8Array(res)
        // 将二进制数据转为字符串
        const temp = utf8decoder.decode(u8arr)
        if (temp.includes('{code:199999')) {
            Message({
                // 字符串转为 JSON 对象
                message: JSON.parse(temp).msg,
                type: 'error',
                duration: 5000,
            })
            return Promise.reject()
        }
    }
    // 正常类型接口,省略代码...
    return res
}, (error) => {
    // 省略代码...
    return Promise.reject(error)
})
目录
相关文章
|
3月前
|
前端开发 JavaScript Java
前端限制打包文件数量
前端限制打包文件数量
184 65
|
3月前
|
前端开发
前端引入字体文件
文章介绍了如何在前端项目中引入字体文件,并展示了具体的HTML和CSS代码示例,包括如何使用`@font-face`规则来定义字体和在页面中应用自定义字体。
84 1
前端引入字体文件
|
1月前
|
前端开发 API
前端界面生成PDF并导出下载
【10月更文挑战第21天】利用合适的第三方库,你可以在前端轻松实现界面生成 PDF 并导出下载的功能,为用户提供更方便的文档分享和保存方式。你还可以根据具体的需求进一步优化和定制生成的 PDF 文件,以满足不同的业务场景要求。
|
3月前
|
前端开发 JavaScript API
前端JS读取文件内容并展示到页面上
前端JavaScript使用FileReader API读取文件内容,支持文本类型文件。在文件读取成功后,可以通过onload事件处理函数获取文件内容,然后展示到页面上。
120 2
前端JS读取文件内容并展示到页面上
|
2月前
|
前端开发 JavaScript
💥【exceljs】纯前端如何实现Excel导出下载和上传解析?
本文介绍了用于处理Excel文件的库——ExcelJS,相较于SheetJS,ExcelJS支持更高级的样式自定义且易于使用。表格对比显示,ExcelJS在样式设置、内存效率及流式操作方面更具优势。主要适用于Node.js环境,也支持浏览器端使用。文中详细展示了如何利用ExcelJS实现前端的Excel导出下载和上传解析功能,并提供了示例代码。此外,还提供了在线调试的仓库链接和运行命令,方便读者实践。
452 5
|
2月前
|
JavaScript 前端开发 编译器
吐血整理:纯前端如何实现批量dom转图片,并下载成压缩包
【10月更文挑战第2天】吐血整理:纯前端如何实现批量dom转图片,并下载成压缩包
65 2
|
3月前
|
前端开发
前端diff文件对比使用worker进行优化
如何使用Web Worker在React项目中优化文件对比差异功能的实现。
50 5
|
2月前
|
资源调度 前端开发 安全
前端实战:基于Verdaccio搭建私有npm仓库,轻松上传与下载自定义npm插件包
前端实战:基于Verdaccio搭建私有npm仓库,轻松上传与下载自定义npm插件包
137 0
|
2月前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
202 0
|
2月前
|
前端开发 JavaScript API
前端基于XLSX实现数据导出到Excel表格,以及提示“文件已经被损坏,无法打开”的解决方法
前端基于XLSX实现数据导出到Excel表格,以及提示“文件已经被损坏,无法打开”的解决方法
224 0