文件上传

前端html页面

<form action="" method="post" enctype="multipart/form-data">
    <input type="file" name="the_file"/>
</form>Code language: HTML, XML (xml)

  1. 请求方式必须为 POST
  2. 表单属性 enctype="multipart/form-data"
  • 默认表单编码application/x-www-form-urlencoded无法传输二进制文件,缺少该属性浏览器不会上传文件
  1. <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)

Previous:
Next:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注