【问题标题】:do_POST not working on http.server with pythondo_POST 无法使用 python 在 http.server 上工作
【发布时间】:2016-08-22 21:15:48
【问题描述】:

我正在尝试创建一个具有基本 GET 和 POST 功能的简单 http 服务器。该程序应该通过打印一个简单的网页来获取请求,该网页向用户打招呼并询问他希望如何被打招呼。当用户输入他选择的问候语时,网页现在应该按照他选择的方式问候他。

虽然 GET 似乎工作正常,但 POST 却不行。我尝试通过在每次代码执行时打印来进行调试,但它似乎卡在这里:

ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))

我将在下面粘贴代码完整代码,以及我的终端输出。

代码:

    from http.server import BaseHTTPRequestHandler, HTTPServer
    import cgi


    class webServerHandler(BaseHTTPRequestHandler):

        def do_GET(self):
            try:
                if self.path.endswith("/hello"):
                    self.send_response(200)
                    self.send_header('Content-type', 'text/html')
                    self.end_headers()
                    output = ""
                    output += "<html><body>"
                    output += "<h1>Hello!</h1>"
                    output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
                    output += "</body></html>"
                    self.wfile.write(output.encode(encoding = 'utf_8'))
                    print (output)
                    return

                if self.path.endswith("/hola"):
                    self.send_response(200)
                    self.send_header('Content-type', 'text/html')
                    self.end_headers()
                    output = ""
                    output += "<html><body>"
                    output += "<h1>&#161 Hola !</h1>"
                    output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
                    output += "</body></html>"
                    self.wfile.write(output.encode(encoding = 'utf_8'))
                    print (output)
                    return

            except IOError:
                self.send_error(404, 'File Not Found: %s' % self.path)

        def do_POST(self):
            try:
                self.send_response(201)
                print("Sent response")
                self.send_header('Content-type', 'text/html')
                print("Sent headers")
                self.end_headers()
                print("Ended header")
                ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
                print("Parsed headers")
                if ctype == 'multipart/form-data':
                    fields = cgi.parse_multipart(self.rfile, pdict)
                    messagecontent = fields.get('message')
                print("Receiver message content")
                output = ""
                output += "<html><body>"
                output += " <h2> Okay, how about this: </h2>"
                output += "<h1> %s </h1>" % messagecontent[0]
                output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
                output += "</body></html>"
                print(output)
                self.wfile.write(output.encode(encoding = 'utf_8'))
                print ("Wrote through CGI")
            except:
                pass


    def main():
        try:
            port = 8080
            server = HTTPServer(('', port), webServerHandler)
            print ("Web Server running on port", port)
            server.serve_forever()
        except KeyboardInterrupt:
            print (" ^C entered, stopping web server....")
            server.socket.close()

    if __name__ == '__main__':
        main()

终端输出:

Web Server running on port 8080
127.0.0.1 - - [28/Apr/2016 13:28:59] "GET /hello HTTP/1.1" 200 -
<html><body><h1>Hello!</h1><form method='POST'      enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form></body></html>
127.0.0.1 - - [28/Apr/2016 13:29:09] "POST /hello HTTP/1.1" 201 -
Sent response
Sent headers
Ended header

如您所见,POST 函数似乎并没有超出 parse_header 命令的范围。我想不通,任何帮助都是有用的!

【问题讨论】:

  • 您的问题表明您使用的是 Python 3,为避免混淆,您应该包括您正在使用的 Python 版本并期望它可以工作:)

标签: python server cgi


【解决方案1】:

现在为时已晚。但是,我仍然会发布这个答案,因为我在学习在线教程时遇到了同样的问题。希望,如果有人偶然发现同样的问题,这会对某人有所帮助。

在教程中,讲师使用的是 python 2,而我使用的是 python 3.6。

Changelog 与讲师所说的对比:

  • 在解析标头时使用 get 方法而不是 getheader,因为 self.headers 是类“MessageClass”的实例。并提供get方法。
  • 在解析多部分消息之前将边界转换为字节。

这里是工作代码的副本

from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi

class webserverHandler(BaseHTTPRequestHandler):
    """docstring for webserverHandler"""

def do_GET(self):
    try:
        if self.path.endswith("/hello"):
            self.send_response(200)
            self.send_header('Content-Type', 'text/html')
            self.end_headers()

            output = ""
            output += '<html><body>Hello!'
            output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
            output += '</body></html>'
            self.wfile.write(output.encode())
            print(output)
            return

        if self.path.endswith("/hola"):
            self.send_response(200)
            self.send_header('Content-Type', 'text/html')
            self.end_headers()

            output = ""
            output += '<html><body>&#161Hola <a href="/hello">Back to Hello</a>'
            output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
            output += '</body></html>'
            self.wfile.write(output.encode())
            print(output)
            return

    except IOError:
        self.send_error(404, "File not found %s" % self.path)

def do_POST(self):
    try:
        self.send_response(301)
        self.send_header('Content-Type', 'text/html')
        self.end_headers()
        ctype, pdict = cgi.parse_header(self.headers.get('Content-Type'))
        pdict['boundary'] = bytes(pdict['boundary'], "utf-8")
        if ctype == 'multipart/form-data':
            fields = cgi.parse_multipart(self.rfile, pdict)
            messagecontent = fields.get('message')
        output = ''
        output += '<html><body>'
        output += '<h2> Okay, how about this: </h2>'
        output += '<h1> %s </h1>' % messagecontent[0].decode("utf-8")
        output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
        output += '</body></html>'
        self.wfile.write(output.encode())
        print(output)
    except:
        self.send_error(404, "{}".format(sys.exc_info()[0]))
        print(sys.exc_info())


def main():
try:
    port = 8000
    server = HTTPServer(('', port), webserverHandler)
    print("Web server running on port %s" % port)
    server.serve_forever()

except KeyboardInterrupt:
    print(" ^C entered stopping web server...")
    server.socket.close()

    if __name__ == '__main__':
        main()

【讨论】:

    【解决方案2】:

    除了 Arpit Jain 的回答之外,我还必须添加 content_len = int(self.headers.get('Content-length'))pdict['CONTENT-LENGTH'] = content_len 才能使其正常工作。

    以下是完整代码,

    from http.server import BaseHTTPRequestHandler, HTTPServer
    import cgi
    import sys
    
    class webserverHandler(BaseHTTPRequestHandler):
        """docstring for webserverHandler"""
    
        def do_GET(self):
            try:
                if self.path.endswith("/hello"):
                    self.send_response(200)
                    self.send_header('Content-Type', 'text/html')
                    self.end_headers()
    
                    output = ""
                    output += '<html><body>Hello!'
                    output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
                    output += '</body></html>'
                    self.wfile.write(output.encode())
                    print(output)
                    return
    
                if self.path.endswith("/hola"):
                    self.send_response(200)
                    self.send_header('Content-Type', 'text/html')
                    self.end_headers()
    
                    output = ""
                    output += '<html><body>&#161Hola <a href="/hello">Back to Hello</a>'
                    output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
                    output += '</body></html>'
                    self.wfile.write(output.encode())
                    print(output)
                    return
    
            except IOError:
                self.send_error(404, "File not found %s" % self.path)
    
        def do_POST(self):
            try:
                self.send_response(301)
                self.send_header('Content-Type', 'text/html')
                self.end_headers()
                ctype, pdict = cgi.parse_header(self.headers.get('Content-Type'))
                content_len = int(self.headers.get('Content-length'))
                pdict['boundary'] = bytes(pdict['boundary'], "utf-8")
                pdict['CONTENT-LENGTH'] = content_len
                if ctype == 'multipart/form-data':
                    fields = cgi.parse_multipart(self.rfile, pdict)
                    message_content = fields.get('message')
                output = ''
                output += '<html><body>'
                output += '<h2> Okay, How about this: </h2>'
                output += '<h1> %s </h1>' % message_content[0]
                output += '<form method="POST" enctype="multipart/form-data" action="/hello"><h2> What would you like me to say?</h2><input name="message" type="text" /><input type="submit" value="Submit" /></form>'
                output += '</body></html>'
                self.wfile.write(output.encode())
                print(output)
            except:
                self.send_error(404, "{}".format(sys.exc_info()[0]))
                print(sys.exc_info())
    
    
    def main():
        try:
            port = 8080
            server = HTTPServer(('', port), webserverHandler)
            print("Web server running on port %s" % port)
            server.serve_forever()
    
        except KeyboardInterrupt:
            print(" ^C entered stopping web server...")
            server.socket.close()
    
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 2018-11-29
      • 2020-11-19
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      相关资源
      最近更新 更多