
一、第一种方式是前端创建超链接,通过a标签的链接向后端服务发get请求或者是window.location.href,接收后端的文件流
const download = (url, fileName) => { const link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', fileName) document.body.appendChild(link) link.click()}
location.href或者是a标签直接指向一个文件的话,浏览器会下载该文件,对于单文件下载没有什么问题,但是如果下载多文件,点击过快就会重置掉前面的请求,href链接静态资源而且适用于浏览器无法识别文件,如果是html、jpg、pdf等会直接解析展示,而不会下载
下载文件
window.open可以打开一个新窗口,虽然能通过这种方式下载文件,但是新的窗口不会关闭,明显体验上不好
二、方式通过创建form表单的方式
利用form表单提交能发起浏览器请求,并且也可以作为多文件下载来使用
var params = {// 参数 id:xx, name:xx }; var form = document.createElement('form') form.id = 'form' form.name = 'form' document.body.appendChild (form) for (var obj in params) { if (params.hasOwnProperty(obj)) { var input = document.createElement('input') input.tpye='hidden' input.name = obj; input.value = params[obj] form.appendChild(input) } } form.method = "GET" //请求方式 form.action = runEnv.api_url+'请求地址' form.submit() document.body.removeChild(form)},
三、会对后端发的post请求,使用blob格式,后端返回文件二进制流
mdn 上是这样介绍 Blob 的:
Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据,axios,设置responseType: 'arraybuffer',接收二进制流
axios({ method: 'post', url: '/export', responseType: 'arraybuffer',}).then(res => { // 假设 data 是返回来的二进制数据 const data = res.data const url = window.URL.createObjectURL(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})) const link = document.createElement('a') link.style.display = 'none' link.href = url const fileNames = res.headers['content-disposition'] // 获取到Content-Disposition;filename const regFileNames = decodeURI(fileNames.match(/=(.*)$/)[1]) link.setAttribute('download', regFileNames) document.body.appendChild(link) link.click() document.body.removeChild(link)})
四、获取文件下载文件流的实时进度(进度条)
文件下载功能体验不友好,特别是下载一些比较耗时的文件,用户在页面上傻等不知道下载的进度是怎么样的,总以为是系统卡死了,所以需要一个进度显示
后台主要是要返回计算好的文件大小,否则上面前端计算进度的时候取的total永远是0,这个就是一个隐藏的坑。(请求返回头添加content-length)
export const dowloadFile = (data, callback) => { return request({ url: 'file/downloadFile', method: 'post', responseType: 'blob', data: data, onDownloadProgress (progress) { callback(progress) } })}async batchDownloadFile (id) { this.percentage = 0 this.$refs.FileProgress.progressShow = true const res = await batchDownloadFile(id, this.processCallback) if (res.status !== 200) { this.$message.warning('下载失败') this.$refs.FileProgress.progressShow = false // 关闭进度条显示层 return false } const fileNames = res.headers['content-disposition'] // 获取到Content-Disposition;filename const regFileNames = decodeURI(fileNames.match(/=(.*)$/)[1]) const url = window.URL.createObjectURL(new Blob([res.data])) const link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', regFileNames) document.body.appendChild(link) link.click() this.$refs.FileProgress.progressShow = false // 关闭进度条显示层 }, processCallback (progressEvent) { const progressBar = Math.round(progressEvent.loaded / progressEvent.total * 100) this.percentage = progressBar },
本文地址:[https://www.chuanchengzhongyi.com/detail/10074.html]