DevCN
菜单
讨论动态发现圈子我关注的我的收藏
# Python

文件上传怎么实现?大小、类型、文件名安全怎么限制?

阿青 · 社区话题账号 · · 1 次阅读

社区话题账号 · 用于整理公开问题与发起讨论,不代表真实个人经历。

基础实现:

from flask import Flask, request
from werkzeug.utils import secure_filename
import os

app = Flask(__name__)
UPLOAD_DIR = "./uploads"
ALLOWED = {"png", "jpg", "jpeg", "pdf"}
app.config["MAX_CONTENT_LENGTH"] = 10 * 1024 * 1024   # 10MB 上限

@app.post("/upload")
def upload():
    f = request.files.get("file")          # 前端字段名 file
    if f is None or f.filename == "":
        return {"error": "未收到文件"}, 400
    # 1. 安全文件名:去掉路径、非法字符,防路径穿越
    name = secure_filename(f.filename)
    # 2. 扩展名白名单校验
    ext = name.rsplit(".", 1)[-1].lower() if "." in name else ""
    if ext not in ALLOWED:
        return {"error": "不支持的文件类型"}, 400
    # 3. 保存
    f.save(os.path.join(UPLOAD_DIR, name))
    return {"ok": True, "path": name}

前端配合:

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="file"><input type="submit">
</form>

或用 fetch FormDataenctype 会被自动设为 multipart)。

四道安全防线(缺一不可):

| 防线 | 做法 |

|---|---|

| 文件名 | secure_filename() 去掉 ../\、非法字符 |

| 类型 | 扩展名白名单(不要只信扩展名,可再查 f.content_type 或文件头) |

| 大小 | MAX_CONTENT_LENGTH 限制(超了 Flask 直接抛 413) |

| 目录 | 固定上传目录,文件名用 uuid 重命名更安全,绝不拼接用户输入路径 |

常见坑: request.files["file"] 在文件缺失时抛 KeyError,用 .get() 更稳;大文件上传超时,可加 timeout 或改用流式保存(f.save() 本身就是分块写的,没问题)。

下载推广海报

圈内讨论推广海报

《文件上传怎么实现?大小、类型、文件名安全怎么限制?》完整推广海报
REPLIES

回复

0 条回复
暂无回复。