Python:如何从BaseHTTPRequestHandler HTTP POST处理程序获取键/值对?

pis*_*hio 45 python post http

给定最简单的HTTP服务器,如何在BaseHTTPRequestHandler中获取post变量?

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_POST(self):
        # post variables?!

server = HTTPServer(('', 4444), Handler)
server.serve_forever()

# test with:
# curl -d "param1=value1&param2=value2" http://localhost:4444
Run Code Online (Sandbox Code Playgroud)

我只想能够获得param1和param2的值.谢谢!

adw*_*adw 58

def do_POST(self):
    ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
    if ctype == 'multipart/form-data':
        postvars = cgi.parse_multipart(self.rfile, pdict)
    elif ctype == 'application/x-www-form-urlencoded':
        length = int(self.headers.getheader('content-length'))
        postvars = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1)
    else:
        postvars = {}
    ...
Run Code Online (Sandbox Code Playgroud)

  • 最新版本的Python在urlparse中使用parse_qs和parse_qsl函数而不是cgi. (10认同)

d33*_*tah 29

我试图编辑帖子并被拒绝,所以这个代码的版本应该适用于Python 2.7和3.2:

from sys import version as python_version
from cgi import parse_header, parse_multipart

if python_version.startswith('3'):
    from urllib.parse import parse_qs
    from http.server import BaseHTTPRequestHandler
else:
    from urlparse import parse_qs
    from BaseHTTPServer import BaseHTTPRequestHandler

class RequestHandler(BaseHTTPRequestHandler):

    ...

    def parse_POST(self):
        ctype, pdict = parse_header(self.headers['content-type'])
        if ctype == 'multipart/form-data':
            postvars = parse_multipart(self.rfile, pdict)
        elif ctype == 'application/x-www-form-urlencoded':
            length = int(self.headers['content-length'])
            postvars = parse_qs(
                    self.rfile.read(length), 
                    keep_blank_values=1)
        else:
            postvars = {}
        return postvars

    def do_POST(self):
        postvars = self.parse_POST()
        ...

    ...
Run Code Online (Sandbox Code Playgroud)

  • 在 Python 3.8 中,“urllib.parse.parse_qs()”为我返回字节而不是字符串,既作为字典的键又作为值。如何让它返回一个包含键和值作为字符串的字典? (4认同)
  • 对于那些感兴趣为什么它有效的人:您可能会奇怪地注意到“parse_reader()”开始准确地读取请求正文所在的位置。这可能是因为一些代码在读取顶行然后请求标头之前。每次读取都会增加读/写指针的位置。如果您要在解析标头和此代码之间读取“self.rfile”,则此解决方案将无法按预期工作。意识到。 (2认同)
  • @SergeRogatch 有效观察(也在Python 3.10中)。快速修复:使用“bytes.decode()”方法将字节转换为字符串,该方法默认使用 UTF-8 。单行代码: `pstr = { key.decode(): [ v.decode() for v in vals ] for key, vals in postvars.items() }` 然后返回 `pstr` (这使得它成为一个二元组)衬垫)。 (2认同)