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

Flask跨服务器传文件时接收端request.files为空的问题

Flask服务器间文件传输:request.files为空触发KeyError问题

问题场景

在两台Flask服务器(Server 1与Server 2)间双向传输文件时,Server 1能正常接收文件,但将文件转发至Server 2后,Server 2的request.files对象为空,访问request.files['file']时触发KeyError。

服务器代码

Server 1 原代码

from flask import Flask, request
import requests

app = Flask(__name__)

@app.route('/test', methods=['POST'])
def test():
    file = request.files['file'].read()
    print(file)
    
    response = requests.post(url="http://127.0.0.1:5002/test",
                             headers=request.headers,
                             files={'file': file}
                             )
    
    return response.json(), response.status_code

if __name__ == "__main__":
    app.run(port=5000)

Server 2 原代码

from flask import Flask, request

app = Flask(__name__)

@app.route('/test', methods=["POST"])
def test():
    file = request.files['file']  # <-- 此处触发KeyError
    print(file)
    
    return 1, 200

if __name__ == "__main__":
    app.run(port=5002, debug=True)

报错信息

127.0.0.1 - - [23/Mar/2024 10:09:02] "POST /test HTTP/1.1" 500 -
Traceback (most recent call last):
  File "C:\Users\gratu\anaconda3\envs\ML\lib\site-packages\flask\app.py", line 1488, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\gratu\anaconda3\envs\ML\lib\site-packages\flask\app.py", line 1466, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\gratu\anaconda3\envs\ML\lib\site-packages\flask\app.py", line 1463, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\gratu\anaconda3\envs\ML\lib\site-packages\flask\app.py", line 872, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\gratu\anaconda3\envs\ML\lib\site-packages\flask\app.py", line 870, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\gratu\anaconda3\envs\ML\lib\site-packages\flask\app.py", line 855, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
  File "C:\Users\gratu\Projects\flasktest\app2.py", line 10, in test
    file = request.files['file']
  File "C:\Users\gratu\anaconda3\envs\ML\lib\site-packages\werkzeug\datastructures\structures.py", line 192, in __getitem__
    raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'file'

问题原因与解决思路

核心问题点

  1. 文件传递格式错误:Server 1中调用request.files['file'].read()后,传递给requests.post的是字节流,而files参数需要的是文件对象或包含文件名、文件对象、MIME类型的元组,直接传字节流会导致Server 2无法解析为文件。
  2. 头部冲突:直接传递request.headers会覆盖requests自动生成的multipart/form-data头部(包含boundary分隔符),导致Server 2无法识别请求中的文件部分,最终request.files为空。

修改后的Server 1代码

from flask import Flask, request
import requests

app = Flask(__name__)

@app.route('/test', methods=['POST'])
def test():
    # 获取原始文件对象,避免直接读取字节流
    file_obj = request.files['file']
    # 读取文件内容后重置指针,确保转发时能重新读取
    print(file_obj.read())
    file_obj.seek(0)
    
    # 转发时使用正确的files格式,不手动传递headers
    response = requests.post(
        url="http://127.0.0.1:5002/test",
        files={'file': (file_obj.filename, file_obj, file_obj.content_type)}
    )
    
    return response.json(), response.status_code

if __name__ == "__main__":
    app.run(port=5000)

优化后的Server 2代码(增加异常处理)

from flask import Flask, request, abort

app = Flask(__name__)

@app.route('/test', methods=["POST"])
def test():
    # 先检查是否存在文件部分
    if 'file' not in request.files:
        abort(400, description="No file part in request")
    file = request.files['file']
    # 检查是否选择了文件
    if file.filename == '':
        abort(400, description="No file selected")
    
    print(file.read())
    return {"status": "success"}, 200

if __name__ == "__main__":
    app.run(port=5002, debug=True)

关键说明

  • 使用file_obj.seek(0):因为调用read()后文件指针会移动到末尾,重置指针才能让转发时正确读取文件内容。
  • 不传递自定义headers:requests在发送multipart/form-data请求时会自动生成包含boundary的Content-Type头部,手动传递原头部会破坏这一机制,导致Server 2无法解析文件。
  • 正确的files参数格式:元组(文件名, 文件对象, 内容类型)能让Server 2正确识别并解析文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:17:06