美文网首页
接口导出文件下载的几种情况

接口导出文件下载的几种情况

作者: 云鹤道人张业斌 | 来源:发表于2024-03-04 14:29 被阅读0次

前提:利用接口导出一个文件,前端会遇到的几种情况。这里主要记录一下文件流太大的情况

1. 导出接口直接给的文件流
  • 文件不大的时候,我们直接使用a标签交给浏览器来下载
function downOSSUrl(url) {
  const a = document.createElement('a')
  a.href = url
  a.rel = 'noreferrer'
  document.body.appendChild(a)
  a.click()
  a.remove()
}

  • 文件大的时候,直接使用以上方式就不太合适,接口处理太慢了,点击后页面没啥反应,还以为有bug。那就获取状态加个loading吧
// request 是封装的axios。 主要是注明一下 responseType: 'blob' 
     this.exportLoading = true
       request({ url:'exportURL', params, responseType: 'blob' }).then(res => {
         this.exportLoading = false
         if (res === 0) {
           this.$message.warning(提示语)
         }
       }).catch(() => {
         this.exportLoading = false
       })

拦截一下axios。 下面的链接超时时间timeout以及nginx的超时时间我们都改大一些

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  timeout: 300000 // request timeout
})

service.interceptors.response.use(
   response => {
    if (response.config.responseType === 'blob' && response.status === 200) {
      if (response.data.size === 0) {
        return 0
      }
      const filename = response.headers['content-disposition'].split(';')[1].split('=')[1]
      const blob = new Blob([response.data])
      const downloadElement = document.createElement('a')
      const href = window.URL.createObjectURL(blob) // 创建下载的链接
      downloadElement.href = href
      downloadElement.download = filename // 下载后文件名
      document.body.appendChild(downloadElement)
      downloadElement.click() // 点击下载
      document.body.removeChild(downloadElement) // 下载完成移除元素
      window.URL.revokeObjectURL(href) // 释放掉blob对象
      return
    }
}
)

以上代码可以看到两个点

(1)response.data.size 长度为0 ,我这里直接返回0.
因为后端考虑到处理时间太长,机器负载问题,限制了一分钟内不能同时多次下载,直接抛错。当多次请求到后端时体现在接口返回内容上,流的长度就是0,此时提示用户:稍后再试
(2)当有信息的时候呢,那就是有两种情况。
一种是包含错误信息或者提示信息, 一种是真正的文件信息。上面代码只考虑了直接下载文件信息。
当和后端有约定要展示特定条件的提示信息时,可以增加以下判断。将流用 filereader解析程json

if(response.headers['content-type'].includes('json')){
   const fileReader = new FileReader()
  fileReader.readAsText(response.data, 'utf-8')
 fileReader.onload = function(res){
   ....
  }
}  

(3) 文件名从响应头中的content-disposition拿到,没有的话,要后端导出

其实相比于直接用a标签交给浏览器下载,这样的请求后下载的,是直接写入到浏览器内存的,所以可以看到整个请求也包含了download的时间,再到磁盘,才会在浏览器上看到进入了下载中心

2. 导出接口给的是有正常响应体,resultoss地址,那拿到地址后再直接去a标签下载即可
3. 接口处理时间太长,出现504 gateway time-out,很明显nginx太久没拿到服务端结果,给了前端504。 设置nginx代理响应时间

(1)上面有个axios 请求超时的时间,以毫秒为单位。设置大点,这里超时是主动断开了,但是后端还在处理。
(2)nginx 设置超时时间,单位是秒。可以设置在http全局模块,server模块,或者是location特定模块。

location /api {
proxy_read_timeout 300;   // 代理读取超时时间
proxy_send_timeout       300;    // 代理发送超时时间
proxy_connect_timeout       300;  // 代理连接超时时间
}

相关文章

网友评论

      本文标题:接口导出文件下载的几种情况

      本文链接:https://www.haomeiwen.com/subject/gunlzdtx.html