Python/CGI/Ajax:cgi.FieldStorage未接收到参数

3

我正在尝试让Python、cgi模块、ajax/javascript组合工作。由于我的服务器访问方式(基本上是租用的网络空间),我无法安装像django或其他任何web框架之类的东西。现在我只能使用cgi。我可以调用python文件来简单地打印出一些内容,但一旦涉及到将参数传递给python文件时,cgi.FieldStorage()就不能接收到任何输入。当我为FieldStorage添加一个打印语句时,输出如下:

FieldStorage(None, None, [])

以下是所有必要的代码。基本上,我正在尝试做的事情(出于测试目的)是从文本输入中获取一个字符串,在其末尾加上“1”并返回它。

有趣的是,当我使用一个简单的php文件来完成完全相同的任务,并将其用于完全相同的脚本时,该脚本可以正常工作,没有任何问题。下面是我尝试过的典型php脚本:

<?php
$user = urldecode(implode(file('php://input')));
$adj_user = $user . "1";
echo $adj_user;
?>

请注意,我想使用Python,因为它更符合我的习惯,而且我不太喜欢PHP。
我有点儿笨,可能是很简单的问题。非常感谢您的帮助找出我的错误。提前致谢!
附言:在发布这个问题之前,我已经在stackoverflow和网络上搜索了相当长的时间。虽然有许多相关主题,但没有一个像我所问的(看起来)那么简单。如果这个问题已有答案,请给我一个链接,谢谢。
回溯如下:
Traceback (most recent call last):
  File "/home/www/xxxxx/html/cgi-bin/hello.py", line 14, in &lt;module&gt;
    adj_user = form['user'] +  "1"
  File "/usr/lib/python2.5/cgi.py", line 567, in __getitem__
    raise KeyError, key
KeyError: 'user'

这里是“index.html”文件。
<!DOCTYPE html>
<html>
    <head>
    <title>Report</title>
    <script type='text/javascript' src='test.js'></script>
    </head>
    <body>
    <form method="post" action=""> 

    <p>Please enter your name here:
    <input type="text" name="user">

    <input type="submit" name="submit" value="Submit" onClick="return hello(this.form.user.value);">
    </p>

    </form>
    </body>
</html>

这是“test.js”文件:
function hello(user) {
    // Mozilla version
    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    }
// IE version
    else if (window.ActiveXObject) {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    //user=encodeURIComponent(user);
    xhr.open("POST", "../cgi-bin/hello.py");
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
    xhr.send(user);

    xhr.onreadystatechange=function() {
        if (xhr.readyState===4) {
            adj_user = xhr.responseText;
            alert ("Hello " + adj_user);
        }
    }
    return false;
}

最后,在我的服务器的cgi-bin目录中,还有一个名为"hello.py"的文件。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import cgi
form = cgi.FieldStorage()

# enable debugging
import cgitb
cgitb.enable()

print "Content-Type: text/html;charset=utf-8"
print

adj_user = form['user'] +  "1"
print adj_user

编辑

我有些进展,但还不是我想要的结果。我将以下代码块更改为:

    xhr.open("GET", "../cgi-bin/hello.py?user=" + user, true);
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
    xhr.send();

请注意从POST到GET的更改以及后缀“”?user=”+ user”,以及send()方法中“user”参数的删除。
现在这样做可以实现我想要的效果,但这种方式似乎不太合适。必须有一种方法可以使用经典方式来解决这个问题...
通常情况下,任何尝试或建议都是受欢迎的。我真的不知道还能尝试什么。谢谢大家。
1个回答

3

application/x-www-form-urlencoded 数据的格式如下:

key=value&key2=value2

在这里,键和值都是URL编码的。

您只需发布字段的值,而没有键。

var postData = encodeURIComponent('user') + '=' + encodeURIComponent(user);
xhr.send(postData);

PHP代码能够正常工作的原因是因为您读取了原始POST数据,而不是$_POST ['user'](这是Python等效的内容)。
您还需要访问form ['user'] .value ,而不是form ['user'] 。这将返回一个 str ,因此您不能在没有执行类型转换的情况下将其与 + 1 连接起来。

非常感谢您的回答!不幸的是,我不太明白您的意思,也无法让我的代码与您编写的内容一起工作。(我只是将代码中的行与未关闭的 'postData' 变量交换了一下。) 您能否为我写出相关的代码块呢?我还是相当新手ajax,请多包涵。谢谢! - Nebelhom
在JavaScript方面,只需用上面的两行代码替换发送行。我也发现了Python方面的问题,并已更新答案。 - Quentin
谢谢,伙计。这就做到了。但它仍然不如我希望的那样动态。我仍然需要为每个传递的变量编写一个 "encodeURIComponent('key') + '=' + encodeURIComponent(key)" 代码块,如果你有3个或更多的变量,这可能会变得相当冗长,但我会将你的答案标记为已接受。谢谢,伙计,你是个明星!一旦我能够(显然需要22小时),我会把+50奖励给你,除非当然有人想出一种动态输入键的方法。 - Nebelhom
你不需要对每一行都这样做,这就是数组存在的意义。 - Quentin
这里有一个例子:http://jsbin.com/ujucoc/1/,虽然我还没有为选择框、复选框、单选按钮和按钮做任何特殊处理。 - Quentin
那绝对回答了我的问题,伙计。非常感谢!继续保持好工作 :) - Nebelhom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接