使用AWS SAM与FlaskLambda时无法获取请求体的问题
AWS SAM + FlaskLambda 无法读取POST请求体问题
应用代码
import json from flask import request from flask_lambda import FlaskLambda app = FlaskLambda(__name__) @app.route('/submission', methods=['GET', 'POST']) def send_submissions(): if request.method == 'GET': return ( json.dumps({ 'name': request.headers['Name'] }), 200, {'Content-Type': 'application/json'} ) elif request.method == 'POST': data = request.get_json() return ( json.dumps({ 'name': request.headers['Name'], 'data': data }), 200, {'Content-Type': 'application/json'} ) if __name__ == '__main__': app.run(debug=True)
出现的错误
调用request.get_json()时触发以下异常:
Traceback (most recent call last): File "/var/task/flask/app.py", line 2190, in wsgi_app response = self.full_dispatch_request() File "/var/task/flask/app.py", line 1486, in full_dispatch_request rv = self.handle_user_exception(e) File "/var/task/flask/app.py", line 1484, in full_dispatch_request rv = self.dispatch_request() File "/var/task/flask/app.py", line 1469, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) File "/var/task/app.py", line 20, in send_submissions data = request.get_json() File "/var/task/werkzeug/wrappers/request.py", line 611, in get_json data = self.get_data(cache=cache) File "/var/task/werkzeug/wrappers/request.py", line 423, in get_data rv = self.stream.read() File "/var/task/werkzeug/wsgi.py", line 829, in readall data = self.read(1024 * 64) File "/var/task/werkzeug/wsgi.py", line 810, in readinto b[:out_size] = data TypeError: can assign only bytes, buffers, or iterables of ints in range(0, 256)
改用request.get_data()时会抛出类似异常;使用request.form.to_dict()则返回空字典。
测试请求代码
headers = {'Name': 'Foo', 'Content-Type': 'application/json'} r = requests.post(f"{base_url}/submission", data={"message": "Hello, World!"}, headers=headers)
问题分析与解决办法
1. 请求参数传递错误
你设置了Content-Type: application/json请求头,但用data参数传递字典,requests会默认将字典编码为application/x-www-form-urlencoded格式,导致后端无法识别为JSON数据。
修复请求代码:改用json参数传递数据,requests会自动完成JSON编码并设置正确的Content-Type(手动指定也可):
headers = {'Name': 'Foo'} r = requests.post(f"{base_url}/submission", json={"message": "Hello, World!"}, headers=headers)
2. FlaskLambda兼容性问题
FlaskLambda项目长期未维护,与新版本Flask(2.x+)、Werkzeug存在兼容性bug,其中就包含请求体流处理异常,导致无法读取请求体。
替代方案:使用aws-wsgi库
aws-wsgi是AWS官方支持的工具,可将Flask应用转换为Lambda兼容的WSGI handler,兼容性更强:
- 安装依赖:
pip install aws-wsgi - 修改应用代码:
import json from flask import Flask, request import aws_wsgi app = Flask(__name__) @app.route('/submission', methods=['GET', 'POST']) def send_submissions(): if request.method == 'GET': return json.dumps({'name': request.headers['Name']}), 200, {'Content-Type': 'application/json'} elif request.method == 'POST': data = request.get_json() return json.dumps({'name': request.headers['Name'], 'data': data}), 200, {'Content-Type': 'application/json'} def handler(event, context): return aws_wsgi.response(app, event, context) if __name__ == '__main__': app.run(debug=True) - 在SAM模板中配置Lambda handler为
app.handler(假设代码文件名为app.py)
3. 测试验证
- 本地测试可直接使用Flask开发服务器,确认请求能正常获取JSON数据;
- 部署前建议用
sam local invoke或sam local start-api测试,排查环境差异问题。
内容的提问来源于stack exchange,提问作者milkbonefun
相关产品推荐
相关产品推荐

