Python CGI脚本接收HTTP请求参数时遇TypeError:not indexable错误求助
咱们一步步拆解你的问题,先理清楚核心错误原因,再给出针对性的解决方案:
错误原因分析
你遇到的TypeError: not indexable加上日志里的End of script output before headers,其实是三个问题叠加导致的:
AJAX请求配置错误
你用的是GET请求,却设置了contentType: "application/json; charset=utf-8"。GET请求的参数应该通过URL的查询字符串传递(比如script.py?low_value=500&high_value=4000),而不是放到请求体里。而且cgi.FieldStorage()默认只解析application/x-www-form-urlencoded或multipart/form-data格式的参数,完全不会处理JSON格式的请求体——这就导致arguments这个FieldStorage实例内部没有正确加载到参数,后续调用getvalue时就触发了"not indexable"的错误。Python脚本的拼写错误
你写了high_value = arguments.gervalue("high_value"),这里是getvalue不是gervalue,这个拼写错误后续也会导致报错。缺少CGI响应头
日志里的End of script output before headers说明你的脚本没有输出必须的HTTP响应头。CGI脚本要求先输出Content-Type这类头信息,然后空一行,再输出内容,否则Web服务器会判定脚本执行失败。
修正后的代码
第一步:修正AJAX请求
去掉不必要的contentType配置,GET请求下jQuery会自动把data里的参数编码成查询字符串拼到URL后面,另外注意datatype要改成规范的驼峰写法dataType:
<script type=text/javascript> $.ajax({ url: "path/to/script.py", data: { "low_value": 500, "high_value": 4000 }, type: "GET", dataType: "json", // 删掉contentType,GET请求不需要它 }); </script>
第二步:修正Python CGI脚本
修复拼写错误,加上必须的响应头,还可以设置默认值避免参数不存在时返回None的问题:
#! /path/to/python import cgi import json # 解析GET参数 arguments = cgi.FieldStorage() # 读取参数,可设置默认值避免None的问题 low_value = arguments.getvalue("low_value", "0") # 修正拼写错误:gervalue → getvalue high_value = arguments.getvalue("high_value", "0") # 必须先输出HTTP响应头,空行分隔头和内容 print("Content-Type: application/json") print() # 处理逻辑后返回JSON response = {"low_value": low_value, "high_value": high_value} print(json.dumps(response))
如果你确实需要用JSON传递参数(POST场景)
如果是POST请求要传JSON,那cgi.FieldStorage()就不适用了,得手动读取请求体并解析JSON:
POST版AJAX请求
<script type=text/javascript> $.ajax({ url: "path/to/script.py", data: JSON.stringify({ "low_value": 500, "high_value": 4000 }), type: "POST", dataType: "json", contentType: "application/json; charset=utf-8" }); </script>
POST版Python脚本
#! /path/to/python import sys import json # 读取POST请求体的JSON数据 try: request_body = sys.stdin.read() arguments = json.loads(request_body) except json.JSONDecodeError: arguments = {} low_value = arguments.get("low_value", "0") high_value = arguments.get("high_value", "0") # 输出响应头 print("Content-Type: application/json") print() response = {"low_value": low_value, "high_value": high_value} print(json.dumps(response))
内容的提问来源于stack exchange,提问作者MapleSyrup

