当前位置: 首页>后端>正文

文件下载常用几种方式

一、第一种方式是前端创建超链接,通过a标签的链接向后端服务发get请求或者是window.location.href,接收后端的文件流

  const download = (url, fileName) => {
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.setAttribute('download', fileName)
      document.body.appendChild(link)
      link.click()
}

location.href或者是a标签直接指向一个文件的话,浏览器会下载该文件,对于单文件下载没有什么问题,但是如果下载多文件,点击过快就会重置掉前面的请求,href链接静态资源而且适用于浏览器无法识别文件,如果是html、jpg、pdf等会直接解析展示,而不会下载

<a href="https://www.clzczh.top/medias/test.html">下载文件</a>

window.open可以打开一个新窗口,虽然能通过这种方式下载文件,但是新的窗口不会关闭,明显体验上不好

二、方式通过创建form表单的方式

利用form表单提交能发起浏览器请求,并且也可以作为多文件下载来使用

    var params = {// 参数
        id:xx,
        name:xx
    };

    var form = document.createElement('form')
    form.id = 'form'
    form.name = 'form'
    document.body.appendChild (form)
    for (var obj in params) {
        if (params.hasOwnProperty(obj)) {
            var input = document.createElement('input')
            input.tpye='hidden'
            input.name = obj;
            input.value = params[obj]
            form.appendChild(input)
        }
    }
    form.method = "GET" //请求方式
    form.action = runEnv.api_url+'请求地址'
    form.submit()
    document.body.removeChild(form)
},

三、会对后端发的post请求,使用blob格式,后端返回文件二进制流

mdn 上是这样介绍 Blob 的:

Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据,axios,设置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
  const fileNames = res.headers['content-disposition'] // 获取到Content-Disposition;filename
  const regFileNames = decodeURI(fileNames.match(/=(.*)$/)[1])
  link.setAttribute('download', regFileNames)
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
})

四、获取文件下载文件流的实时进度(进度条)

文件下载功能体验不友好,特别是下载一些比较耗时的文件,用户在页面上傻等不知道下载的进度是怎么样的,总以为是系统卡死了,所以需要一个进度显示
后台主要是要返回计算好的文件大小,否则上面前端计算进度的时候取的total永远是0,这个就是一个隐藏的坑。(请求返回头添加content-length)


文件下载常用几种方式,第1张
export const dowloadFile = (data, callback) => {
  return request({
    url: 'file/downloadFile',
    method: 'post',
    responseType: 'blob',
    data: data,
    onDownloadProgress (progress) {
      callback(progress)
    }
  })
}

async batchDownloadFile (id) {
      this.percentage = 0
      this.$refs.FileProgress.progressShow = true
      const res = await batchDownloadFile(id, this.processCallback)
      if (res.status !== 200) {
        this.$message.warning('下载失败')
        this.$refs.FileProgress.progressShow = false // 关闭进度条显示层
        return false
      }
      const fileNames = res.headers['content-disposition'] // 获取到Content-Disposition;filename
      const regFileNames = decodeURI(fileNames.match(/=(.*)$/)[1])
      const url = window.URL.createObjectURL(new Blob([res.data]))
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.setAttribute('download', regFileNames)
      document.body.appendChild(link)
      link.click()
      this.$refs.FileProgress.progressShow = false // 关闭进度条显示层
 },
 processCallback (progressEvent) {
      const progressBar = Math.round(progressEvent.loaded / progressEvent.total * 100)
      this.percentage = progressBar
 },

https://www.xamrdz.com/backend/38h1939178.html

相关文章: