根据后端返回的地址下载PDF文件

需求
在谷歌(Chrome)浏览器中,使用a标签属性download下载pdf链接文件,如果是相同域时,可以直接下载;但是如果域不同,则不是下载,而是直接打开页面预览文件。但是需求是直接点击下载文件,而不是打开预览;以及下载后台返回的文件流。

方法一

/*
 * 根据后端返回的pdf文件的地址,下载pdf文件
 *  url 完整的路径
 *  fileName 文件名
 * type 文件类型,如.pdf
 */
const fileLinkToStreamDownload = (url: string, fileName: any, type: any) => {
    let reg = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\/])+$/
    if (!reg.test(url)) {
        throw new Error('传入参数不合法,不是标准的文件链接')
    } else {
        let xhr = new XMLHttpRequest()
        xhr.open('get', url, true)
        xhr.setRequestHeader('Content-Type', `application/${type}`)
        xhr.responseType = 'blob'
        xhr.onload = function () {
            if (this.status == 200) {
                //接受二进制文件流
                var blob = this.response
                downloadExportFile(blob, fileName, type)
            }
        }
        xhr.send()
    }
}

const downloadExportFile = (blob: any, tagFileName: any, fileType: any) => {
    let downloadElement = document.createElement('a')
    let href = blob
    if (typeof blob == 'string') {
        downloadElement.target = '_blank'
    } else {
        href = window.URL.createObjectURL(blob) //创建下载的链接
    }
    downloadElement.href = href
    downloadElement.download = tagFileName + moment(new Date().getTime()).format('YYYYMMDDhhmmss') + '.' + fileType //下载后文件名
    document.body.appendChild(downloadElement)
    downloadElement.click() //点击下载
    document.body.removeChild(downloadElement) //下载完成移除元素
    if (typeof blob != 'string') {
        window.URL.revokeObjectURL(href) //释放掉blob对象
    }
}

方法二

插件

安装   
npm install web-downloadfile

使用

import { base64ToFileOrBlob, saveFileToBlob, saveFileToLink } from 'web-downloadfile';

 <a onClick={() => { saveFileToLink('完整的URL地址', '文件名', '.文件类型') }}>下载</a>

插件三种方法的使用

一,base64ToFileOrBlob
主要针对图片 base64转blob对象 或 直接下载文件 但是文件也可用
  import { base64ToFileOrBlob } from 'web-downloadfile';
  let Blob = base64ToFileOrBlob(base64,'',true);
  // or
  base64ToFileOrBlob(base64,'',false);

  //获取图片的文件流
  let blob = base64ToBlob('data:image/png;base64,iVBORw0KGgo=...','image/png')
 downloadExportFile(blob, 'download', 'png')



二,saveFileToBlob
主要用于文件导出下载 支持大部分文件类型 但是文件类型必传
  import { saveFileToBlob } from 'web-downloadfile';
  saveFileToBlob(Blob,'test','xlsx');

//后端返回数据流格式文件,可用该方法导出文件
 const exportFile = () => {
    service.exportFile(postObj).then((res: any) => {
      saveFileToBlob(res, 'test', 'xlsx');
      //后端返回blob格式文件流,前端进行转码,得到url,实现下载文件功能
      // let blob = new Blob([res], {
      //   type: 'application/vnd.ms-excel'
      // })
      // let objectUrl = URL.createObjectURL(blob)
      // method.downloadFile(objectUrl, 'text.xlsx')
      // message.success('导出成功')
    })
  }
  


三,saveFileToLink
主要pdf文件链接的下载 因为pdf文件链接在浏览器会直接打开 但是其他文件的链接也可以下载 可监听文件下载进度
link必须允许跨越访问 否则无法下载
  import { saveFileToLink } from 'web-downloadfile';
  saveFileToLink(link,'test','jpg',fn);

下载文件(不限制文件格式)

// 下载文件
function downloadByURI(data: string, fileName: string, header: string = '') {
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = header + data
    link.download = fileName
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
}

function downloadByBlob(url, fileName) {
    axios
        .get(url, {
            responseType: 'blob',
        })
        .then((res: any) => {
            const content = res.data
            const blob = new Blob([content])
            const tempFileName = fileName
            const link = document.createElement('a')
            if ('download' in link) {
                link.download = tempFileName
                link.style.display = 'none'
                link.href = URL.createObjectURL(blob)
                link.click()
                URL.revokeObjectURL(link.href)
                document.body.removeChild(link)
            } else {
                $message.error('暂不支持下载')
            }
        })
        .catch(e => {
            console.log(e)
        })
}

版权声明:本文为jdrunk原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。