接口返回二进制文件流,前端通过blob对象实现下载

场景:项目中请求图片或者下载文件一般情况下都是接口返回url或者接口本身就是一个get请求访问接口直接下载。但是在某些情况下,接口会返回一个二进制文件流,在控制台打印或者network的preview中就是一串看不懂的字符串(下图)

第一次遇到的时候也是一脸迷茫,就顺着惯性思维总觉得接口返回的不对。但其实只是自己技术有限,没有接触到而已。这就是接口返回的文件的二进制流,通过js的Blob对象是可以转成文件下载下来的。

二进制流转图片:如果接口返回的是个图片,前端需求是展示这个图片,可以直接将api放到img标签的src中,和普通ajax请求的接口一样,这样在浏览器network中可以看到这个图片和请求一样,不过类型成了img类型的。

二进制流下载:借助blob对象,直接贴代码

      let xhr = new XMLHttpRequest()
      let fileName = 'file.docx' // 文件名称 
      xhr.open('GET', Api, true)
      xhr.responseType = 'arraybuffer'
      xhr.setRequestHeader(token, 'xxxxx') // 请求头中的验证信息等(如果有)
      xhr.onload = function() {
        if (this.status === 200) {
          let type = xhr.getResponseHeader('Content-Type')

          let blob = new Blob([this.response], {type: type})
          if (typeof window.navigator.msSaveBlob !== 'undefined') {
            /*
             * IE workaround for "HTML7007: One or more blob URLs were revoked by closing
             * the blob for which they were created. These URLs will no longer resolve as 
             * the data backing the URL has been freed." 
             */
            window.navigator.msSaveBlob(blob, fileName)
          } else {
            let URL = window.URL || window.webkitURL
            let objectUrl = URL.createObjectURL(blob)
            if (fileName) {
              var a = document.createElement('a')
              // safari doesn't support this yet
              if (typeof a.download === 'undefined') {
                window.location = objectUrl
              } else {
                a.href = objectUrl
                a.download = fileName
                document.body.appendChild(a)
                a.click()
                a.remove()
              }
            } else {
              window.location = objectUrl
            }
          }
        }
      }
      xhr.send()

09/12更新:

在接口做验证的时候,如果验证失败,接口返回json信息,但是由于设置了responseType='arraybuffer',这时候this.response将不再是json字符串,而是ArrayBuffer对象,要处理它来将后台返回的信息展示出来。

let uint8 = new Uint8Array(this.response) // 提取uint8Array
let resToString = decodeURIComponent(escape((String.fromCharCode(...uint8)))) // 解决乱码

得到的resToString就是后台返回的json字符串了。

只通过String.fromCharCode会出现中文乱码的情况

前端进行文件下载,通常是通过调用后台接口获取文件,然后在浏览器端触发一个下载操作。使用Vue框架时,可以通过axios等HTTP请求库来获取后台数据,再配合一些前端JavaScript代码来实现文件下载。以下是一个简单的示例实现: ```javascript <template> <button @click="downloadFile">下载文件</button> </template> <script> export default { methods: { downloadFile() { // 使用axios发送请求,获取文件 axios({ url: '后台接口地址', // 请替换为实际的接口地址 method: 'GET', responseType: 'blob', // 告诉浏览器响应体是blob类型,这样文件下载时才能正确处理 timeout: 10000 }).then(response => { // 创建一个URL对象,用于读取响应的blob数据 const url = window.URL.createObjectURL(new Blob([response.data])); // 创建一个a标签用于下载 const link = document.createElement('a'); link.href = url; link.setAttribute('download', '文件名.xlsx'); // 设置下载文件名,可以包含后缀 // 把a标签添加到文档中,模拟点击实现下载 document.body.appendChild(link); link.click(); // 下载完成后移除a标签 document.body.removeChild(link); }).catch(error => { console.error('下载文件失败:', error); }); } } }; </script> ``` 在这个示例中,点击按钮会触发`downloadFile`方法。这个方法通过axios向后台请求文件数据,设置`responseType`为`blob`以确保响应数据被作为二进制数据处理。获取到文件后,使用`window.URL.createObjectURL`创建一个可下载的URL,然后创建一个`a`标签,设置其`href`属性为这个URL,并通过设置`download`属性指定下载文件名。最后模拟点击`a`标签触发下载,并在下载后将其从文档中移除。 请注意,根据实际需求,后台接口地址、请求方式、文件名以及请求参数等都需要根据实际情况进行调整。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值