0
点赞
收藏
分享

微信扫一扫

前端文件流下载填坑之旅

凯约 2022-06-30 阅读 74

在一个地方连续踩了2次坑,对于我这种记性不好的来说,只能博客赶紧记录一下了,文件流下载的适用场景是: 前端页面点击导出按钮后调取后端接口,接口返回数据,然后通过下载函数处理,下载保存到本地,下面分享下都遇到哪些坑:


一. 接口需配置 responseType

// xx 导出
export function handleExport(params, type) {
  return request({
    url: `xxxxx/export`,
    method: 'post',
    data: params,
    responseType: type,
  })
}

二. 调用接口并传参

/**
 * 导出
*/
handleExport() {
  this.$confirm('确定要导出所有线下订单吗?', '导出提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
  }).then(async () => {
    this.exportLoading = true
    const exportRes = await handleExport(parmas, 'blob').catch((err) => {
      this.exportLoading = false
    })
    this.exportLoading = false
    downloadFile(exportRes, '线下订单明细')
  })
},
/**
 * @description axios响应拦截器
 */
instance.interceptors.response.use(
  (response) => {
    console.log(response) // 此处可以打印先看下返回的数据格式,方便下面处理
    const { config, data, status } = response
    const exportUrlList = [`${shopUrl}/orderItem/export`]
    if (exportUrlList.includes(config.url)) {
      // 导出接口,返回数据格式与其他不统一,需特殊处理
      if (status === 200) {
        return data
      } else {
        Vue.prototype.$baseNotify('导出失败!', '提示', 'error')
        return Promise.reject({
          noShow: true,
          message: '导出失败!',
        })
      }
    } else {
      return handleData(response) // 这是其他的统一处理的函数
    }
  },
  (error) => {
    const { response } = error
    if (response === undefined) {
      Vue.prototype.$baseMessage('未可知错误,大部分是由于后端不支持跨域CORS或无效配置引起', 'error')
      return {}
    } else return handleData(response)
  }
)

 

三. 下载,保存到本地

/**
 * @description 下载文件流
 * @param response 文件流
 * @param fileName 文件名称
 */
export function downloadFile(response, fileName) {
  const blob = new Blob([response])
  const a = document.createElement('a')
  const URL = window.URL || window.webkitURL // 兼容webkix浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
  a.href = URL.createObjectURL(blob) // 根据解析后的blob对象创建URL 对象
  a.download = `${fileName}-` + moment().format('YYYYMMDDHHmmss') + '.xls'
  //此写法兼容可火狐浏览器
  document.body.appendChild(a)
  let evt = document.createEvent('MouseEvents')
  evt.initEvent('click', false, false)
  a.dispatchEvent(evt)
  document.body.removeChild(a)
}

 四. 文件保存后,验证是否可以正常打开


举报

相关推荐

0 条评论