【问题标题】:Extending BaseHTTPRequestHandler - getting the posted data扩展 BaseHTTPRequestHandler - 获取发布的数据
【发布时间】:2026-02-15 04:45:02
【问题描述】:

我已经看到this 的问题,但我希望能够从处理程序外部访问经过 POST 处理的数据。

有没有办法做到这一点?

以下是代码:

import BaseHTTPServer

HOST_NAME = ''
PORT_NUMBER=8088

postVars = ''

class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def do_POST(s):
        s.send_response(200)
        s.end_headers()
        varLen = int(s.headers['Content-Length'])
        postVars = s.rfile.read(varLen)
        print postVars

server_class = BaseHTTPServer.HTTPServer
httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)

try:
    httpd.handle_request()
except KeyboardInterrupt:
    pass

print postVars
httpd.server_close()

postVars 在 Handler 期间被赋值,但在 MyHandler 之后不被赋值

【问题讨论】:

    标签: python http networking variables


    【解决方案1】:

    这是因为postVars在HTTPServer创建的MyHandler实例中受到本地影响。如果要访问它,请在do_POST 方法的开头将postVars 声明为全局变量。

    def do_POST(s):
      global postVars
      s.send_response(200)
      s.end_headers()
      varLen = int(s.headers['Content-Length'])
      postVars = s.rfile.read(varLen)
    

    无论如何,我不确定你想通过在服务器和 requestHandler 上下文之外使用变量来实现什么。

    【讨论】:

    • 如此简单,被赞成和接受(我需要全局 var,因为在我获取数据后,我有大量其他处理要做,并且将其嵌入到处理程序中将不起作用)
    • 不知道你的真实上下文,但处理大量后处理的最佳方法是将 POST 数据放在某种queue 中,并有一个后端服务器进程消耗排队。
    • 为什么唯一的解决方案是使用全局变量?
    【解决方案2】:

    BaseHTTPServer 可作为BaseHTTPRequestHandler 的属性使用。这意味着您可以使 postVar 在服务器上可用。

    如果您将BaseHTTPServer 子类化为:

    class MyServer(BaseHTTPServer.HTTPServer):
        def __init__(self, *args, **kwargs):
             # Because HTTPServer is an old-style class, super() can't be used.
             BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
             self.postVars = None
    

    您可以使用此服务器将 postVars 保存在服务器上,例如:

    class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    
        def do_POST(s):
            s.send_response(200)
            s.end_headers()
            varLen = int(s.headers['Content-Length'])
            s.server.postVars = s.rfile.read(varLen)
            print postVars
    

    然后当然使用MyServer而不是BaseHTTPServer:

    server_class = MyServer
    httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
    
    print httpd.postVars
    

    通常,该解决方案比使用全局变量更可取。

    【讨论】:

    • 这应该是公认的答案。全局变量通常会在以后引起严重的头痛。非常感谢
    • 这是最好的答案。在我几个小时的搜索过程中,我知道我需要将它存储在服务器中,因为每次 GET 操作后都会生成一个新的请求处理程序实例。我需要找到一种访问服务器的方法,如果不在这里,我将阅读所有源代码。在我的课堂上,self.server 给那些想要复制的人大声笑