Python/CGI/Ajax: cgi.FieldStorage does not receive arguments
Question: I am trying to get a Python, cgi module, ajax/javascript combination to work.
Due to the nature of my server access (essentially rented webspace), I cannot
install things like django or any other webframework. I am stuck with cgi for
now. I am able to call the python file to simply print out something, but once
it comes to passing an argument to the python file the cgi.FieldStorage() does
not receive any input. When I add a print statement for the FieldStorage, the
output is as follows:

    
    
    FieldStorage(None, None, [])
    

You can find all the necessary code below. Essentially, all I am trying to do
(for testing purposes) is to get a string from a text input, add a "1" to the
end of it and return it.

Interestingly, when I use a simple php file that does the exact same thing and
use it in the otherwise exact same script, the script works without any
issues. Here's a typical php script that I tried:

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

(Please note that I want to use python, because I am far more comfortable with
it and I dislike php quite a bit.)

I have the feeling that I am just a little bit dense and it is something very
simple. Any help in finding what I am doing wrong is very appreciated. Thanks
a lot in advance!

P.S. I have scoured stackoverflow and the web quite some time before I posted
on here. There are many related topics, but nothing quite as (seemingly)
simple as what I am asking. If there is an answered duplicate to this question
then I apologise and would be grateful for a link. Thanks again.

The traceback is:

    
    
    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'
    

Here is the "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>
    

This is the "test.js" file:

    
    
    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;
    }
    

and lastly "hello.py" in my server's cgi-bin

    
    
    #!/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
    

* * *

_EDIT_

I made some progress, but it still isn't what I am hoping for. I changed the
following block as follows:

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

Please note the change from POST to GET and the suffix ' "?user=" + user ', as
well as the removal of the 'user' argument in the send() method.

Now this does, what I want, but it just shouldn't "be" that way. There must be
a way to get this to work the classical way...

As usual, any attempt or suggestion is welcome. I really don't know what else
to try. Thanks fellas.


Answer: The format of `application/x-www-form-urlencoded` data is:

    
    
    key=value&key2=value2
    

… where the keys and values are URL encoded.

You are posting just the value of a field, with no keys.

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

The reason that the PHP code was working was because you was reading the raw
POST data instead of `$_POST['user']` (which is what your Python was
equivalent to).

You also need to access `form['user'].value` rather than `form['user']`. That
will return a `str` so you can't concatenate it with `+ 1` without performing
type conversion.

