简体   繁体   中英

Accessing fields with Python CGI FieldStorage from a JQuery AJAX call

I have written some JQuery that makes an ajax call to a Python script. I've been successful in passing strings back and forth between them, but I'm getting weird behaviour from the CGI FieldStorage object that I'm using to get the input in the Python script. I've also managed to send a simple object with key/value pairs, like this:

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

Here is my python script, 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())

When I run the javascript, it correctly prints out the keys in my object, ie ["two", "one"] (I'm not sure why they're reversed). I can also get the corresponding values by replacing the last line of simple.py with something like print json.dumps(fs["one"].value) .

However, when I try to make a multi-level object (an object within an object), I get weird behaviour. For example, I kept the deptObj that I had already created, then passed in data: { departments: deptObj} to the ajax call. Then, when I tell simple.py to print out the keys, the result is ["departments[two]", "departments[one]"] instead of what I would expect, ["departments"] . Then, since "departments" is apparently not a key, I get a KeyError when I try print json.dumps(fs["departments"].value) , while print json.dumps(fs["departments[one]"].value) gives me a result of 1.

According to the documentation for FieldStorage , "the fields, accessed through form[key], are themselves instances of FieldStorage", so I thought that my FieldStorage object would have a "departments" key whose value is another FieldStorage object containing the keys "one" and "two". However, this doesn't seem to be true. How do I form a multi-level Javascript object and access it in my python script using FieldStorage?

This is just jQuery being silly. You should set traditional: true in your $.ajax call.

This will not strictly answer your question but I hope it answers the goal rather than the specifics of what you asked. I'm sorry if it's not what you wanted.

jQuery passing the Ajax request whose content type is (by default) application/x-www-form-urlencoded; charset=UTF-8 application/x-www-form-urlencoded; charset=UTF-8 (taken from the jQuery (v1.0 and later) documentation ).

There are a few ways to get the JSON into your python script from the JavaScript. The first is to explicitly make a form field and pass in the 'stringified' JSON structure which you can then parse at the other end. Another is to try and reverse engineer how jQuery is encoding the JSON string and pick apart the encoded fields into a JSON string (which sounds painful).

There is (in my opinion) a better way, which passes the content type as JSON straight away by specifying the content type to be JSON in the Ajax query. For example, changing your jQuery Ajax call to:

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

(that is, adding the type to 'POST' and adding the dataType to 'json' ). And the corresponding Python code:

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

yields what I believe to be your desired result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM