前端html页面
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="the_file"/>
</form>Code language: HTML, XML (xml)
- 请求方式必须为 POST
- 表单属性
enctype="multipart/form-data"
- 默认表单编码
application/x-www-form-urlencoded无法传输二进制文件,缺少该属性浏览器不会上传文件
<input type="file">必须设置name属性,后端通过该name获取文件
后端基础接收代码
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# 获取上传文件对象,the_file 和前端input的name对应
f = request.files['the_file']
# 保存到服务器指定路径(硬编码文件名,会覆盖旧文件)
f.save('/var/www/uploads/uploaded_file.txt')
return "保存成功"
else:
# GET请求,渲染上传页面
return render_template('upload.html')Code language: PHP (php)
request.files:字典结构,存放所有上传文件- 文件对象自带
.save(保存路径)方法,用于写入磁盘
注意
f.filename 获取客户端原始文件名,不可信任,用户可以构造恶意文件名(例如 ../../etc/passwd 路径穿越攻击)。
安全方案:secure_filename()
from werkzeug import secure_filename
f = request.files['the_file']
# 净化文件名,剔除危险路径字符,防止路径穿越
safe_name = secure_filename(f.filename)
f.save('/var/www/uploads/' + safe_name)Code language: PHP (php)
完整例子
from flask import Flask, request, render_template
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
UPLOAD_FOLDER = "/var/www/uploads"
@app.route('/upload', methods=['GET','POST'])
def upload():
if request.method == "POST":
file_obj = request.files["the_file"]
# 校验是否选中文件
if file_obj.filename == "":
return "请选择文件!"
safe_name = secure_filename(file_obj.filename)
save_path = os.path.join(UPLOAD_FOLDER, safe_name)
file_obj.save(save_path)
return "上传成功"
return render_template("upload.html")
if __name__ == '__main__':
app.run(debug=True)Code language: PHP (php)