Javascript 通过JQuery AJAX调用使用Python CGI FieldStorage访问字段

Javascript 通过JQuery AJAX调用使用Python CGI FieldStorage访问字段,javascript,python,jquery,cgi,Javascript,Python,Jquery,Cgi,我已经编写了一些JQuery,可以对Python脚本进行ajax调用。我已经成功地在它们之间来回传递字符串,但是我从CGI FieldStorage对象中得到了奇怪的行为,我正在使用该对象获取Python脚本中的输入。我还成功地发送了一个带有键/值对的简单对象,如下所示: deptObj = { one : '1', two : '2'}; $.ajax({ data: deptObj, url: "simple.py", success: function(resul

我已经编写了一些JQuery,可以对Python脚本进行ajax调用。我已经成功地在它们之间来回传递字符串,但是我从CGI FieldStorage对象中得到了奇怪的行为,我正在使用该对象获取Python脚本中的输入。我还成功地发送了一个带有键/值对的简单对象,如下所示:

deptObj = { one : '1', two : '2'};

$.ajax({
    data: deptObj,
    url: "simple.py",
    success: function(result) { console.log("Success!"); console.log(result); },
    error: function(request, error) { console.log("Error"); console.log(request); }
});
下面是我的python脚本simple.py:

#!/usr/bin/env python
import json
import cgi
import cgitb

print "Content-type: application/json\n\n" 
cgitb.enable() # display error messages in web browser

fs = cgi.FieldStorage()

print json.dumps(fs.keys())
当我运行javascript时,它会正确地打印出对象中的键,即
[“两个”,“一个”]
(我不知道为什么它们会反转)。我还可以通过将simple.py的最后一行替换为类似于
print json.dumps(fs[“one”].value)
的内容来获得相应的值

然而,当我尝试创建一个多级对象(对象中的对象)时,我会得到奇怪的行为。例如,我保留了我已经创建的deptObj,然后将
数据:{departments:deptObj}
传递给ajax调用。然后,当我告诉simple.py打印密钥时,结果是
[“departments[two],“departments[one]”]
而不是我所期望的,
[“departments”]
。然后,由于“departments”显然不是一个键,所以当我尝试打印json.dumps(fs[“departments”].value)时,我得到了一个键错误,而
打印json.dumps(fs[“departments[one]]”.value)
的结果是1


根据“通过表单[key]访问的字段本身就是FieldStorage的实例”,因此我认为我的FieldStorage对象将有一个“departments”键,其值是另一个包含键“one”和“two”的FieldStorage对象。然而,这似乎不是真的。如何形成一个多级Javascript对象并使用FieldStorage在python脚本中访问它?

这只是jQuery的愚蠢之处。您应该在
$.ajax
调用中设置
traditional:true

这不会严格回答您的问题,但我希望它能回答您的目标,而不是您所问的具体问题。如果这不是你想要的,我很抱歉

jQuery传递内容类型为(默认)
application/x-www-form-urlencoded的Ajax请求;字符集=UTF-8
(取自)

有几种方法可以从JavaScript将JSON转换成python脚本。第一种方法是显式生成表单字段并传入“stringified”JSON结构,然后在另一端解析该结构。另一种方法是尝试对jQuery如何编码JSON字符串进行反向工程,并将编码字段分离为JSON字符串(听起来很痛苦)

在我看来,有一种更好的方法,通过在Ajax查询中将内容类型指定为JSON,直接将内容类型作为JSON传递。例如,将jQuery Ajax调用更改为:

deptObj = { one : '1', two : '2'};

$.ajax({
    data: deptObj,
    type: "POST",
    url: "simple.py",
    dataType : "json",
    success: function(result) { console.log("Success!"); console.log(result); },
    error: function(request, error) { console.log("Error"); console.log(request); }
});
(即,将
类型
添加到
'POST'
并将
数据类型
添加到
'json'
)。以及相应的Python代码:

#!/usr/bin/env python
import json
import sys
import cgi
import cgitb
cgitb.enable() # display error messages in web browser

print "Content-type: application/json\n\n" 
print json.dumps( json.load( sys.stdin ) )

产生我认为是您期望的结果。

这似乎部分解决了问题-现在
fs.keys()
给了我“部门”,但我仍然不知道如何访问“一”和“二”<代码>fs[“部门”]。值在我的Web Inspector控制台中显示为
[对象]
,不带任何字段
fs.getlist(“部门”)
给了我类似的东西,
[“[object object]”]
len(fs[“departments”])
给我一个错误,上面写着“AttributeError:MiniFieldStorage实例没有属性‘len’”。有什么想法吗?我也尝试过
fs[“departments”].keys()
,这会导致错误“MiniFieldStorage实例没有属性'keys'”。你只是因为退回到json并使用浏览器控制台而弄糊涂了。在Python脚本中放置一个断点并在那里检查它。在我的脚本中“放置断点”是什么意思?我试着打印python对象(不是JSON),但是如果不打印到我的网站上,这个输出会去哪里呢?我正在查看apache2错误日志,但它没有说明任何有用的内容。您仍然没有说明您要实现的目标。正如我所说的,发布到Python、序列化到JSON、返回到客户机,然后在web inspector中进行检查,这让您感到困惑:步骤太多了,不可能知道哪一步出错。对于调试,一次检查一个步骤:从Python开始,记录到磁盘,而不是返回;然后,忽略帖子,只返回您认为需要的内容,并检查它,等等。一个明显的问题是,您从未在浏览器中反序列化JSON。