前端 通过post请求下载文件方法(原生js)

1,671 阅读1分钟
  • 废话少说直接上代码 这边利用ajax和blob 模拟下载
// 前提如果报 跨域的错 请联调后端解决跨域问题
/**
 * post 下载通用方法
 * @param {string} url 请求地址
 * @param {object} data 请求体
 * @param {string} filename 文件名称 如果不传会根据后端的Content-Disposition信息来组织 但前提后端要暴露这个头部信息 否则会出现 refuse的情况
 * @param {function} callback // 回调
 */
export function downloadFile(url, data, filename, callback) {
  const xhr = new XMLHttpRequest()
  xhr.open('POST', url, true)
  xhr.responseType = 'blob'
  xhr.onload = ev => {
    const currentTarget = ev.currentTarget || {}
    if (currentTarget.status === 200 && currentTarget.readyState === 4) {
      if (!filename) {
        // 从头部信息解析出 文件名称   这边可能会报错 unsafe refuse 的错 这是后端没有暴露此请求头
        const disposition = xhr.getResponseHeader('Content-Disposition')
        if (disposition && disposition.indexOf('attachment') !== -1) {
          const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
          const matches = filenameRegex.exec(disposition)
          if (matches != null && matches[1])
            filename = matches[1].replace(/['"]/g, '')
        }
      }
      const type = xhr.getResponseHeader('Content-Type')
      const blob = new Blob([currentTarget.response], { type: type })
      // 针对一些不同浏览器进行一些兼容操作 下载
      if (window.navigator.msSaveBlob) {
        window.navigator.msSaveBlob(blob, filename)
      } else {
        const URL = window.URL || window.webkitURL
        const downloadUrl = URL.createObjectURL(blob)

        if (filename) {
          const a = document.createElement('a')
          if (a.download === undefined) {
            window.location = downloadUrl
          } else {
            a.href = downloadUrl
            a.download = filename
            document.body.appendChild(a)
            a.click()
          }
        } else {
          window.location = downloadUrl
        }
        setTimeout(() => {
          URL.revokeObjectURL(downloadUrl)
        }, 100) // 释放资源
      }
    }
    callback && callback()
  }
  /** 如果需要一些头部信息在此处添加 */
  xhr.setRequestHeader('Content-type', 'application/json')
  xhr.send(JSON.stringify(data))
}