In a Python3 CGI script, how can I read the raw form data in a POST?

我只是一个虾纸丫 提交于 2020-01-03 16:58:29

问题


Yes, I'm aware of cgi.FieldStorage, but, being some form of unordered dictionary, it does not preserve the order of the original data (see below for proof). Since I wish to use this data with PayPal IPN, order is important PayPal docs here, which say "...you must send back the contents in the exact order they were received..."

Alternatively, os.environ.get('QUERY_STRING') looks perfect, however, it seems to only work for a GET. Example code: (myscript.py)

#!/usr/bin/python3

import cgi, os

query = os.environ.get('QUERY_STRING') or 'no query'
print ("Content-type: text/plain\n\n")
print("query=" + query)
form = cgi.FieldStorage()
for key in form.keys():
   print("\n" + key + '=' + form.getvalue(key))

Works with a GET from the browser, e.g. (note that foo is before ggg)

http://example.com/myscript.py/foo=bar&ggg=3&aaa=bbb&zzz=qqq

returns

query=foo=bar&ggg=3&aaa=bbb&zzz=qqq
ggg=3
foo=bar   << note that foo now comes after ggg
aaa=bbb
zzz=qqq

However, if I use Postman to POST

POST /myscript.py HTTP/1.1
Host: example.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

foo=bar&ggg=3&aaa=bbb&zzz=qqq

It returns no query string, and, as expected, the FormData did not preserve the order.

query=no query
ggg=3
foo=bar   << note that foo now comes after ggg
aaa=bbb
zzz=qqq

回答1:


Not sure why nobody answered. After a little futzing I discovered that the solution is incredibly simple. Is that why nobody bothered to answer?

Just read from stdin: (this is Python3 code, not sure if Python2 would be any different)

query_string = sys.stdin.read()

There's one drawback: this is incompatible with cgi.FieldStorage(), since that will also try to read from stdin. So, if you also want a nice dictionary to look up query terms, there is one more simple step:

multiform = urllib.parse.parse_qs(query_string)

which, much like cgi.FieldStorage, returns a multimap, hence the name multiform.

For some more details, I blogged about it here.



来源:https://stackoverflow.com/questions/27556949/in-a-python3-cgi-script-how-can-i-read-the-raw-form-data-in-a-post

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!