xuanweiH / Project-issue

记录项目遇到一些问题与封装
2 stars 0 forks source link

封装一个文件下载 #1

Open xuanweiH opened 4 years ago

xuanweiH commented 4 years ago
import $http from './http'
/**
 * 获取文件后缀名
 * @param {*} filename
 */
function getfilenameExtension (filename) {
  if (typeof filename === 'string') {
    const splits = filename.split('.')
    const splitLen = splits.length
    if (splitLen > 1 && splits[splitLen - 1]) {
      return '.' + splits[splitLen - 1]
    }
  }
  return ''
}
/**
 * 下载
 * @param {*} url 资源路径
 * @param {string} filename 文件名
 */
// 对于文件的资源服务首先存储到后端的 然后再下载文档的需求主要是通过 创建A标签 设置属性download 以及 href 为url实现
export const download = function (url, filename) {
  if (document) {
    let aElem = document.createElement('A')
    filename && aElem.setAttribute('download', filename)
    aElem.setAttribute('href', url)
    aElem.setAttribute('target', '_self')
    aElem.style.display = 'none'
    document.body.appendChild(aElem)
    aElem.click()
    setTimeout(() => {
      document.body.removeChild(aElem)
    })
  }
}
/**
 * 异步下载
 * @param {string} url 请求路径
 * @param {*} data 请求参数
 * @param {*} fileName 下载文件名(可选)不传此参数默认使用服务器返回的文件名
 * @param {*} defautFileName 默认文件名取不到文件名时使用
 */
// 对于后端直接返回文件流的情况, 我们需要自己封装一个处理函数
// 主要通过设置responseType blob 和 responseAll 为true
// 获取的返回结果后 用new FileReader对象的 onload方法 获取到e,target.result 作为url
// 然后再获取fileName 利用A标签 的download属性进行下载
export const ajaxDownload = function (url, data, fileName, defautFileName) {
  return $http.post(url, data, {
    responseType: 'blob',
    responseAll: true
  })
    .then(res => {
      const headers = res.headers
      const data = res.data
      const reader = new FileReader()
      reader.readAsDataURL(data)
      reader.onload = function (e) {
        let extension = getfilenameExtension(fileName)
        let resFileName = ''
        if (!fileName || !extension) {
          const cd = headers['content-disposition']
          const match = cd ? cd.match(/filename=[^;]+/) : null // 取文件名
          if (match) {
            resFileName = match[0].split('=')[1].replace(/"/g, '')
            if (decodeURI && typeof decodeURI === 'function') {
              resFileName = decodeURI(resFileName)
            }
          }
        }
        if (fileName && !extension) {
          fileName += getfilenameExtension(resFileName)
        }
        download(e.target.result, fileName || resFileName || defautFileName)
      }
      return res
    })
}