Flask API本地运行正常,部署至Azure App Service后返回415错误
问题分析与解决方案
核心问题根源
415(不支持的媒体类型)错误的本质是你的GET请求携带了请求体——虽然Flask在本地环境对这种不符合HTTP规范的行为兼容性较好,但Azure App Service的前端代理/网关会严格遵循HTTP标准,直接拦截这类请求,导致请求根本没到达你的Flask应用。
修复方案
方案1:改用POST方法(推荐)
HTTP规范中,GET请求的设计目的是获取资源,不应携带请求体。最规范的修复方式是将接口改为POST:
服务器端代码修改
@app.route(f"{API_ENDPOINT_PREFIX}/filter/<tablename>", methods=["POST"]) # 修改为POST方法 def get_filter_options(tablename: str): request_data = request.get_json() logging.debug(f"Request data: {request_data}") # 原有业务逻辑保持不变 logging.info(f"Retrieved {len(options)} filter options for table '{tablename}'") return jsonify({"filters": options})
客户端调用修改
header = {"Content-Type": "application/json", "Accept": "application/json"} requests.post( # 改用post方法 f"{BASE_API_URL}/filter/tablename", json={"filters": {}}, # 直接使用json参数,无需手动dumps headers=header, )
方案2:保留GET,改用URL查询参数(仅兼容场景使用)
如果必须保留GET方法,把请求体中的参数转移到URL查询字符串中:
客户端调用修改
import json header = {"Accept": "application/json"} requests.get( f"{BASE_API_URL}/filter/tablename", params={"filters": json.dumps({"filters": {}})}, # 将参数转为查询字符串 headers=header, )
服务器端代码修改
@app.route(f"{API_ENDPOINT_PREFIX}/filter/<tablename>", methods=["GET"]) def get_filter_options(tablename: str): # 从查询参数中获取并解析数据 request_data = json.loads(request.args.get("filters", "{}")) logging.debug(f"Request data: {request_data}") # 原有业务逻辑保持不变 logging.info(f"Retrieved {len(options)} filter options for table '{tablename}'") return jsonify({"filters": options})
进一步排查步骤
- 查看Azure日志
- 打开App Service的「日志流」,实时查看请求处理日志,确认415错误是由前端网关还是Flask应用返回的
- 检查应用日志文件,确认
request.get_json()在云端是否有机会执行,排除应用内部的其他异常
- 直接测试接口
- 用Postman等工具向云端接口发送不带请求体的GET请求,查看是否返回其他错误(如500),验证数据库连接是否正常
- 发送带JSON体的POST请求,验证修改后的接口是否能正常响应
- 检查Azure配置
- 确认App Service是否启用了WAF(Web应用防火墙),是否有规则拦截了带请求体的GET请求
- 检查容器启动日志,确认环境变量(如
API_ENDPOINT_PREFIX)是否正确配置,应用是否正常启动
内容的提问来源于stack exchange,提问作者mattiatantardini
相关产品推荐
相关产品推荐

