You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask中将POST请求中的文件保存到本地运行的Minio服务器?

解决Minio上传时的InvalidXMLError问题

看起来你遇到的这个InvalidXMLError本质是Minio客户端和服务器的通信出了问题——返回的内容不是合法的XML格式,导致解析失败。最可能的原因是你调用fput_object时参数传错了:这个方法需要的是本地文件的路径字符串,但你传的是Flask上传的FileStorage对象(也就是代码里的image变量),这就导致客户端无法正确读取文件内容,服务器返回了错误的非XML响应,进而触发了解析报错。

下面给你两种修正方案,推荐第二种更高效的方式:

方案1:临时保存文件后上传

先把Flask接收的文件保存到本地临时路径,再用fput_object上传:

import os
from flask import request
from werkzeug.utils import secure_filename
from minio.error import BucketAlreadyOwnedByYou, BucketAlreadyExists, ResponseError

# 假设你的minioClient已经完成正确初始化
if 'file' in request.files:
    file = request.files['file']
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        # 临时文件路径,可根据实际项目调整存储位置
        temp_path = os.path.join('/tmp', filename)
        file.save(temp_path)
        
        try:
            minioClient.make_bucket("testbuck", location="us-east-1")
        except BucketAlreadyOwnedByYou:
            pass
        except BucketAlreadyExists:
            pass
        except ResponseError as err:
            raise
        try:
            # 传入临时文件路径而非FileStorage对象
            minioClient.fput_object('testbuck', filename, temp_path)
            # 上传完成后清理临时文件
            os.remove(temp_path)
        except ResponseError as err:
            print(err)
            # 出错也要记得删除临时文件
            if os.path.exists(temp_path):
                os.remove(temp_path)

方案2:直接上传文件流(推荐)

用Minio的put_object方法直接读取Flask文件对象的流,不需要临时文件,更节省磁盘空间:

from flask import request
from werkzeug.utils import secure_filename
from minio.error import BucketAlreadyOwnedByYou, BucketAlreadyExists, ResponseError

if 'file' in request.files:
    file = request.files['file']
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        
        try:
            minioClient.make_bucket("testbuck", location="us-east-1")
        except BucketAlreadyOwnedByYou:
            pass
        except BucketAlreadyExists:
            pass
        except ResponseError as err:
            raise
        try:
            # 重置文件指针到开头(Flask可能已读取过一次,指针会停在末尾)
            file.seek(0)
            # 用put_object直接上传文件流
            minioClient.put_object(
                'testbuck',
                filename,
                file,
                length=-1,  # -1表示自动检测文件大小
                content_type=file.content_type
            )
        except ResponseError as err:
            print(err)

额外检查点

  1. 确认你的minioClient初始化是正确的,示例如下:
from minio import Minio

minioClient = Minio(
    'your-minio-endpoint:port',
    access_key='your-access-key',
    secret_key='your-secret-key',
    secure=True  # 如果使用HTTP协议请改为False
)

如果endpoint、密钥配置错误,也可能导致服务器返回非XML的错误响应,引发同样的报错。

  1. 确认allowed_file函数逻辑正确,它需要检查文件名后缀是否在你允许的列表内,避免上传非法文件。

内容的提问来源于stack exchange,提问作者user9798671

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:07:56