Skip to content

关于上传和下载(二) 下载 #18

@Alexandermclean

Description

@Alexandermclean

再说说下载吧,之前我也就构造一个form的dom结构,再通过submit()方法提交,只要后台提供的是正常的文件流的话,浏览器会自动生成文件,但有一点需要注意的是返回头必须是application/octet-stream,这点你可以自己在node层加工一下返回头。但自从我发现了一个叫Blob的类之后就觉得这种方法更方便了,可以像正常的ajax请求一样请求文件流到前端自己处理,就避免了当传参复杂的时候form表单的局限性,具体实现下面细说。

2.下载

至于下载呢,我一直是不太喜欢用前端构造form表单的形式,这样会显得笨重而且麻烦。前端时间写的关于下载安装包文件的需求,根据后台返回的二进制文件流利用Blob对象生成可点击下载的a标签,在dom上节省了很大一部分,而且是基于ajax请求的,因此在传参上很方便。

// 还是先简单的写下构造form表单的下载吧
template部分
<form action='api/xxx/xxx' method='post' id='download' name='downloadForm'>
	<input id='type' type='hidden' name='type' value=''>
</form>

script部分
let type-data = JSON.stringify(object-data) // 如果需要传的参数是对象或者数组之类的,可以先stringify一下
$('#type').attr('value', type-data)
$('#download').submit() // 触发提交表单

这种方式的好处是浏览器会根据返回的二进制文件流自动生成对应的文件,不需要对返回的流做处理

// ajax请求+Blob对象的方式
this.$axios({
	method: 'POST',
	url: 'api/xxx/xxx',
	responseType: 'arraybuffer', // 这里比较重要,要规定后台返回的类型是二进制流,才不会造成文件打不开的情况
	data: {
		type: {xx: xxx}
	}
}).then(r => {
	const blob = new Blob([r.data], {type: 'application/zip'})
	const url = window.URL || window.webkitURL || window.moxURL
	const href = url.createObject(blob)

	let link = document.createElement('a')
	link.href = href
	link.display = none
	document.body.appendChild(link)
	link.click
	document.body.removeChild(link)
})

这样的方式好处就是传参便捷、不用构造form表单和自定义强度高,可以对返回的文件流做自定义加工,例如文件名、文件格式之类,只要在link.click()之前都可以;只是对于node层来说,可能需要对返回的数据做加工,返回的可能就不只是单单一个文件流了,可以以对象的方式返回包含文件名、文件类型、文件大小等参数,便于前台展示。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions