Ajax传参至Python脚本触发TypeError: not indexable错误求助
解决Ajax传参到Python CGI脚本的TypeError: not indexable问题
这个问题我之前帮朋友排查过,核心原因是你的Ajax请求的内容类型和发送的数据格式不匹配,导致Python的cgi.FieldStorage没法正确解析POST数据,才抛出了"not indexable"的错误。
错误根源
你在Ajax里设置了contentType:"application/text-plain; charset=utf-8",但发送的是键值对格式的data: { "x": $("input#name").val() }。而cgi.FieldStorage默认只能解析application/x-www-form-urlencoded(普通表单提交格式)或者multipart/form-data(文件上传格式)的请求,纯文本格式的内容它没法识别成可索引的键值对集合,所以调用getvalue()时就会报错。
两种可行的解决方案
方案一:改用标准表单提交格式(推荐)
直接修正Ajax的contentType为默认的表单格式,jQuery默认就是这个类型,甚至可以不用显式声明:
$.ajax({ type: 'POST', url: 'test.py', cache: false, // 要么去掉这行,要么显式设置为标准表单格式 contentType: "application/x-www-form-urlencoded; charset=utf-8", data: { "x": $("input#name").val() }, success: function(data) { $("p#second").text(data); }, error: function(data){ $("p#second").text("ya sorry nah"); } });
你的Python代码不需要改动,保持原来的逻辑就能正常获取参数,别忘了输出HTTP头部:
#!/usr/bin/env python2.7 import cgi post = cgi.FieldStorage() thing = post.getvalue("x") print("Content-Type: text/plain\n") # 必须输出的HTTP响应头部 print(thing)
⚠️ 注意:Python脚本开头一定要加#!/usr/bin/env python2.7声明解释器,否则服务器可能找不到正确的执行程序。
方案二:直接读取纯文本POST数据(适合特殊场景)
如果你确实需要用纯文本格式传递数据,那就要放弃cgi.FieldStorage,直接从标准输入读取原始数据:
首先修改Ajax,把data改成直接传递输入框的值,而不是键值对:
$.ajax({ type: 'POST', url: 'test.py', cache: false, contentType: "application/text-plain; charset=utf-8", data: $("input#name").val(), // 直接传文本内容,不是键值对 success: function(data) { $("p#second").text(data); }, error: function(data){ $("p#second").text("ya sorry nah"); } });
然后修改Python代码,直接读取sys.stdin的内容:
#!/usr/bin/env python2.7 import sys # 读取原始纯文本数据 thing = sys.stdin.read().strip() print("Content-Type: text/plain\n") print(thing)
额外检查
- 确保你的Python脚本有执行权限(比如在终端执行
chmod +x test.py) - 服务器已经正确配置了CGI支持(比如Apache需要开启
mod_cgi,并把脚本放在指定的cgi-bin目录)
内容的提问来源于stack exchange,提问作者exemplarary
相关产品推荐
相关产品推荐

