Davide Andrea
Davide Andrea

Reputation: 1413

How to get data from FieldStorage?

form= cgi.FieldStorage()
print form

Prints: FieldStorage(None, None, 'age=10&name=joe').

How do I get the data from that form?

I can't use form[FieldKey], because there is no field key.

form['age'] returns a blank string

I'm using Python 2.7.

Upvotes: 3

Views: 13382

Answers (3)

fheshwfq
fheshwfq

Reputation: 375

This happens when FieldStorage parses "plain" POST data, as opposed to a form for example. If the content-type of the HTTP request is application/x-www-form-urlencoded however, it will know what to do.

This is the HTML file that has a single send button, once it is clicked, the name and age data are sent to the proc.py script, after the header is set to what the Python CGI library likes.

<html><body>
<button type="button" onclick="sendData()">Send</button>
<div id="content">No reponse from script yet.</div>
<script>
function sendData() {
    var http = new XMLHttpRequest();
    http.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
        document.getElementById('content').innerHTML = this.responseText;
        }
    };
    http.open('POST', '/cgi-bin/proc.py', true);
    http.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
    http.send('age=10&name=joe');
}
</script>
</body></html>

And proc.py spits these value back:

#!/usr/bin/env python
import cgi
data = cgi.FieldStorage()
print 'Content-type: text/html\n'
print data['name'].value
print '<br />'
print data['age'].value

Upvotes: 2

ggorlen
ggorlen

Reputation: 57135

You can try

import cgi

form = cgi.FieldStorage()
print form.getvalue("age")

as described in the more general thread How are POST and GET variables handled in Python?

Upvotes: 2

Jaymon
Jaymon

Reputation: 5728

Other answers have explained why there was a problem with the request and how to fix it, but I think it might be helpful to better understand the FieldStorage object so you can recover from a bad request.

I was mostly able to duplicate your state using this:

from cgi import FieldStorage
from StringIO import StringIO

f = FieldStorage(
    fp=StringIO("age=10&name=joe"), 
    headers={"content-length": 15, "content-type": "plain/text"}, 
    environ={"REQUEST_METHOD": "POST"}
)

print(f) # FieldStorage(None, None, 'age=10&name=joe')

This will fail as expected:

f["age"] # TypeError: not indexable
f.keys() # TypeError: not indexable

So FieldStorage didn't parse the query string because it didn't know it should, but you can make FieldStorage manually parse it:

f.fp.seek(0) # we reset fp because FieldStorage exhausted it
# if f.fp.seek(0) fails we can also do this:
# f.fp = f.file
f.read_urlencoded()

f["age"] # 10
f.keys() # ["age", "name"]

If you ever need to get the original body from FieldStorage, you can get it from the FieldStorage.file property, the file property gets set when FieldStorage parses what it thinks is a plain body:

f.file.read() # "age=10&name=joe"

Hope this helps other fellow searchers who stumble on this question in the future.

Upvotes: 2

Related Questions