前端用:REACT
后端:FLASK
一、文件的上传
<Tr>
<Td title="缓停清单" span="3">
<Form.Item >
{getFieldDecorator('缓停清单', {
valuePropName: 'fileList',
getValueFromEvent:this.normFile,
})(
<Upload action={`/file/huanting/upload`}
withCredentials
onDownload={this.onDownload}
showUploadList={{showPreviewIcon: false, showRemoveIcon: true, showDownloadIcon: true}}
onChange={this.normFile}
data={{uni_id: this.props.menu.user ? this.props.menu.user.uni_id : null}}>
<Button>
<Icon type="upload"/> 点击此处上传附件
</Button>
</Upload>
)}
</Form.Item>
</Td>
</Tr>
界面显示如下:当点击上传文件后
此时后端可以通过如下语句,获取到对应files流。
files = request.files['file']
将files打印出来,可以看出上传的文件会被flask解析为Werzeug中的FileStorage对象。
flask收到上传的文件后,需要将之保存到数据库中,但是注意,有一步很重要:需要更改文件名。
原因在于:攻击者可能会在文件名中加入恶意路径。假设文件名为:’ …/…/…/home/filename ’ 。那么如果我们保存文件时候,会导致服务器上的系统文件被篡改或者覆盖。
因此file.filename获取到文件名后,需要将之编码。
filename = files.filename
此后就可以通过save()方法 将文件保存到指定目录了。
files.save(uploaded_file_path)
二、文件的下载
当用户在前端点击下载按钮后,会在flask调用一个download的命令。可以使用send_from_directory此方法下载对应文件。
from flask import send_from_directory
folder, filename = get_file_path(file_id)
record_download_file(uni_id, file_id)
return send_from_directory(folder, filename)