SQL Server调用Flask GET接口传JSON遇404及解析失败问题
问题:SQL Server调用Flask GET接口返回404及JSON解析错误
我尝试在SQL Server中将对象数组格式的字符串作为输入,通过本地Flask服务器的GET请求获取JSON响应,但服务器返回404状态码,SQL查询输出错误信息:Expecting value: line 1 column 1 (char 0)。
现有代码
Flask接口代码
@app_bp.route("/example", methods=["GET"]) def example() -> Tuple[flask.wrappers.Response, int]: try: data_out = request.get_data() print(data_out) data_out = json.loads(data_out) print(data_out) except Exception as e: return jsonify({"Error": f"{e}"}), 404 else: return jsonify(data_out), 200
curl测试命令(可正常返回200)
curl -X GET -H "Content-type: application/json" -H "Accept: application/json" -d '[{"test": 101}]' "http://127.0.0.1:3080/api/v1/app/example"
SQL Server请求代码
DECLARE @json_input AS VARCHAR(MAX) = '[{"test": 101}]'; DECLARE @xmlRequestObject INT = 0 DECLARE @urlGet VARCHAR(8000) = 'http://127.0.0.1:3080/api/v1/app/example' DECLARE @return INT = 0 DECLARE @contentType VARCHAR(8000) = 'application/json' DROP TABLE IF EXISTS #json_output CREATE TABLE #json_output ([output] NVARCHAR(MAX)) --Create the XML request object EXEC @return = sp_OACreate 'MSXML2.XMLHTTP', @xmlRequestObject OUT; IF @return <> 0 BEGIN RAISERROR('Unable to open HTTP connection.', 10, 1); RETURN; END --Open the connection EXEC @return = sp_OAMethod @xmlRequestObject, 'OPEN', NULL, 'GET', @urlGet, 'false'; --Set the request headers EXEC @return = sp_OAMethod @xmlRequestObject, 'setRequestHeader', NULL, 'Content-Type','application/json; charset=utf-8' EXEC @return = sp_OAMethod @xmlRequestObject, 'setRequestHeader', NULL, 'Accept','application/json' --Send the request EXEC @return = sp_OAMethod @xmlRequestObject, 'SEND', NULL, @json_input --Handle the response INSERT INTO #json_output ([output]) EXEC sp_OAGetProperty @xmlRequestObject, 'responseText' SELECT * FROM #json_output EXEC sp_OADestroy @xmlRequestObject SELECT * FROM #json_output
错误输出
{ "Error": "Expecting value: line 1 column 1 (char 0)" }
解决方案
- 核心问题:GET请求携带请求体不符合HTTP规范
curl允许GET请求带-d参数,但很多HTTP客户端(包括MSXML2.XMLHTTP)会忽略GET请求的请求体,导致Flask端request.get_data()拿到空字符串,触发JSON解析错误并返回404。
方案1:将Flask接口改为POST(推荐)
修改Flask路由的请求方法为POST,并使用request.get_json()简化JSON解析:
@app_bp.route("/example", methods=["POST"]) def example() -> Tuple[flask.wrappers.Response, int]: try: data_out = request.get_json() print(data_out) except Exception as e: return jsonify({"Error": f"{e}"}), 404 else: return jsonify(data_out), 200
SQL端代码无需修改,POST请求携带请求体是标准行为,MSXML2.XMLHTTP会正常发送请求体内容。
方案2:保留GET,将JSON放入查询参数
如果必须使用GET,需要把JSON数据编码后作为URL查询参数传递:
- Flask端修改为从查询参数获取并解析JSON:
@app_bp.route("/example", methods=["GET"]) def example() -> Tuple[flask.wrappers.Response, int]: try: json_str = request.args.get("data") if not json_str: raise ValueError("Missing 'data' query parameter") data_out = json.loads(json_str) print(data_out) except Exception as e: return jsonify({"Error": f"{e}"}), 404 else: return jsonify(data_out), 200
- SQL端需要对JSON字符串进行URL编码后拼接进URL:
注意:SQL Server无内置URL编码函数,需自行实现CLR函数或使用自定义逻辑编码,避免特殊字符破坏URL结构。示例拼接逻辑(未编码,仅作演示):
DECLARE @urlGet VARCHAR(8000) = 'http://127.0.0.1:3080/api/v1/app/example?data=' + @json_input
额外优化:改用ServerXMLHTTP
MSXML2.ServerXMLHTTP更适合服务器端HTTP请求,行为更标准,可替换原创建对象的代码:
EXEC @return = sp_OACreate 'MSXML2.ServerXMLHTTP', @xmlRequestObject OUT;
内容的提问来源于stack exchange,提问作者ChiragM
相关产品推荐
相关产品推荐

