前端文件下载

<a href="链接" >下载</a>

一个文件链接(一般是服务器上的某个文件),这个链接一般地址栏输入是预览,不是附件下载

如果想改成附件下载

1、后端处理,后端加上一个响应头
res.setHeader('Content-Dispostion', 'attachment', 'name.pdf')

然后当你访问这个链接,浏览器发现有这个相应头,会自动触发下载行为

2、a标签 加上 download属性
<a href="链接" download="文件名" >下载</a>

这种也可以,但是局限性太大,

如果这个文件的下载要求的是携带token,那a标签这种就不生效了(a标签没法携带token)。会成为预览

方案:a标签可以携带cookie,所以可以有另一种解决方法,在下载文件前,发送一个请求获取一个临时token通过cookie进行携带,

a标签下载是流式下载,会把服务器的文件像流水一样存储到本地磁盘,所以下载直接能看到下载,不会将文件缓存到浏览器,

3、写一个方法进行下载 (本质还是利用a标签进行下载)

这个方法可以是一个ajax请求,这个请求就可以携带token,然后将请求到的服务器文件转成blob,在创建一个a标签进行下载,

但是**这种是有问题的,**如果文件小还行,文件大了就会出现点击了下载,但是没有反应,过了几分钟后才出现了下载,

这种等待时间就是将服务器端的那个文件转成了blob,才进行a标签的流式下载,

//获取blob
export function handleGetBlob(url) {
  // console.log(url)
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest()
    xhr.open('GET', url, true)
    xhr.responseType = 'blob'
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response)
      }
    }
    xhr.setRequestHeader('Cache-Control', 'no-cache')
    xhr.send()
  })
}
/**
 * 下载入口
 */
export function downloadFile(url, name) {
  return new Promise((resolve, reject) => {
    handleGetBlob(url)
      .then((blob) => {
        let fileName = url.split('/')
        let fileType = ''
        fileName = fileName[fileName.length - 1]

        fileType = fileName.split('.')
        fileType = fileType[fileType.length - 1]

        let saveName = `${name}.${fileType}`
        if (name.indexOf('.') > -1) {
          saveName = name
          const lastType = name.split('.')[name.split('.').length - 1]
          if (fileType && lastType !== fileType) {
            saveName = `${name}.${fileType}`
          }
        }

        handleSaveAs(blob, saveName)
        resolve()
      })
      .catch((err) => {
        console.log('err', err)
        reject(err)
        // this.$message.warning('下载错误');
      })
  })
}
/**
 * 下载文件并重新命名
 */
export function handleSaveAs(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    navigator.msSaveBlob(blob, filename)
  } else {
    const link = document.createElement('a')
    const body = document.querySelector('body')
    link.href = window.URL.createObjectURL(blob)
    link.download = filename
    // fix Firefox
    link.style.display = 'none'
    body.appendChild(link)
    link.click()
    body.removeChild(link)
    window.URL.revokeObjectURL(link.href)
  }
}