文件下载常用几种方式

和365差不多的平台有哪些 2026-01-15 17:06:49 admin 6179 849
文件下载常用几种方式

一、第一种方式是前端创建超链接,通过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)

image.png

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

},

相关推荐

[欧冠日志]拜仁8:2巴萨复
和365差不多的平台有哪些

[欧冠日志]拜仁8:2巴萨复

10-05 295
用闷闷不乐造句(精选50个句子):
义乌365人工客服电话多少

用闷闷不乐造句(精选50个句子):

09-23 305