如何实现最基本的文件(附件)上传下载?
存储格式
数据库建立Blob/Clob/BYTEA格式的字段用于存储文件的文件流
一、上传
前端
使用基本的 file type类型input。
使用过程中发现该类型默认显示中文,可将其隐藏,添加新的控件来触发此input控件的输入。
input.form-control( type='file' @change="handleGetFile" style="display:none" ref="fileInput" )
.input-group
input.form-control.form-control-sm( type="text" v-model.trim="fileToUpload.file_name" readonly )
.input-group-append
.input-group-btn.btn.btn-sm.btn-info( @click="$refs.fileInput.click()" ) Browse
使用FormData包装file数据,并post到后台服务
handleGetFile(data) {
let formData = new FormData()
formData.append("context_id", this.contextId)
formData.append("file_data", data.target.files[0])
formData.append("file_name", data.target.files[0].name)
formData.append("file_size", data.target.files[0].size)
this.$axios.post('url', formData)
}
后台(python)
在request中取files的数据
# file object hat is being uploaded.
file_data = request.files['file_data']
# read the stream of the file
bin_data = file_data.read()
将bin_data存储数据库Blob/BYTEA字段
二、下载
后台
返回blob/bytea字段file stream数据
前端
前端发送get请求,需要将responseType设为blob,默认为json。
this.$axios.get(`url`, {responseType: 'blob'})
收到response的file stream数据后,创建Blob对象并下载该对象
downloadAttachment(attachment, response.data) {
const blob = new Blob([response.data], {type: attachment.file_type, name: attachment.file_name})
if ('download' in document.createElement('a')) {
const link = document.createElement('a')
link.fileName = attachment.file_name
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
link.setAttribute('download', attachment.file_name)
document.body.appendChild(link)
link.click()
URL.revokeObjectURL(link.href)
document.body.removeChild(link)
}
else {
navigator.msSaveBlob(blob, attachment.file_name)
}
}