Python Flask API接收含特殊字符输入的URL编码处理方法
问题根源
URL 规范中?属于保留字符,作用是分隔 URL 路径段和查询参数段,所有 HTTP 客户端(浏览器、请求库)遇到 URL 中的?时,都会自动将?之后的内容识别为查询参数,不会纳入路径匹配范围,所以原有路由永远匹配不到带?的路径,才会返回 404。此外 Flask 默认的string路由转换器只能匹配不包含/的字符串,碰到带/的参数也会触发 404。
规范解决方案
方案1:使用 POST 请求传递 JSON 参数(最推荐,符合 REST API 设计规范)
不要将复杂参数放在 URL 路径中,改为通过 POST 请求的 Body 传递参数,无需处理任何编码,支持所有特殊字符:
from flask import Flask, jsonify, request app = Flask(__name__) @app.route('/') def index(): return f"请向 {request.url}api 发送 POST 请求,Body 为 JSON 格式的 {{\"body\": \"你的字符串\"}} 即可获取响应" # 修改路由为接受POST请求,不需要路径参数 @app.route('/api', methods=['POST']) def sample(): req_data = request.get_json() # 校验必填参数 if not req_data or 'body' not in req_data: return jsonify({'error': '缺少必填参数body'}), 400 body = req_data['body'] return jsonify({'length': len(body)}) if __name__ == '__main__': app.run(debug=True)
调用方式示例(curl):
curl -X POST -H "Content-Type: application/json" -d '{"body": "测试?特殊/字符&%$#"}' http://127.0.0.1:5000/api
方案2:使用 GET 请求的查询参数传递
如果需要保留 GET 请求方式,可将参数放在查询段,HTTP 客户端会自动对查询参数做 URL 编码,Flask 也会自动解码返回原始字符串:
@app.route('/api', methods=['GET']) def sample(): # 直接从查询参数中获取body,Flask会自动处理解码 body = request.args.get('body', '') return jsonify({'length': len(body)})
调用示例:
请求地址为 http://127.0.0.1:5000/api?body=测试?特殊字符,标准 HTTP 库会自动将?编码为%3F,无需手动处理。
方案3:修改路由转换器(仅兼容原有路径传参的调用逻辑,不推荐)
如果必须保留路径传参的形式,将路由转换器从string改为path,可匹配包含/的路径,同时要求调用方对路径中的保留字符做 URL 编码:
# 用path转换器替代string @app.route('/api/<path:body>') def sample(body): return jsonify({'length': len(body)})
注意:该方案仍要求调用方将路径中的?编码为%3F,否则?后的内容仍会被识别为查询参数,无法被路径匹配。
内容的提问来源于stack exchange,提问作者Yashasvi Bhatt
相关产品推荐
相关产品推荐

