【问题标题】:do_POST method failing in Python 3.6Python 3.6 中的 do_POST 方法失败
【发布时间】:2021-12-25 01:44:41
【问题描述】:

我一直在尝试在 Python 3.6 中制作一个基本的多部分表单。 do_GET 方法运行良好,但 do_POST 方法一直失败。

当我在 Chrome 中提交表单时,它说 localhost 没有发送任何数据。 ERR_EMPTY_RESPONSE,但是当我在开发者控制台中检查网络选项卡时,我可以看到表单值。

代码似乎与 Python 2.7 完美配合。我不确定代码哪里出错了。

这是我写的代码:

from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi


class WebServerHandle(BaseHTTPRequestHandler):
    def do_GET(self):
        try:
            if self.path.endswith("/new"):
                self.send_response(200)
                self.send_header('Content-type', 'text/html')
                self.end_headers()
                output = ""
                output += "<html><head><style>body {font-family: Helvetica, Arial; color: #333}</style></head>"
                output += "<body><h2>Add new Restaurant</h2>"
                output += "<form method='POST' enctype='multipart/form-data' action='/new'>"
                output += "<input name='newRestaurantName' type='text' placeholder='New Restaurant Name'> "
                output += "<input type='submit' value='Add Restaurant'>"
                output += "</form></html></body>"
                self.wfile.write(bytes(output, "utf-8"))
                return
            if self.path.endswith("/restaurant"):
                self.send_response(200)
                self.send_header('Content-type', 'text/html')
                self.end_headers()
                output = ""
                output += "<html><head><style>body {font-family: Helvetica, Arial; color: #333}</style></head>"
                output += "<body><h3>Restaurant name added successfully!</h3>"
                output += "</html></body>"
                self.wfile.write(bytes(output, "utf-8"))
                return
        except IOError:
            self.send_error(404, 'File Not Found: %s' % self.path)

    def do_POST(self):
        try:
            if self.path.endswith("/new"):
                ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
                if ctype == 'multipart/form-data':
                    fields = cgi.parse_multipart(self.rfile, pdict)
                    restaurant_name = fields.get('newRestaurantName')
                    print("Restaurant name is ", restaurant_name)
                    self.send_response(301)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Location', '/restaurant')
                    self.end_headers()
        except:
            print("Something went wrong, inside exception..")


def main():
    try:
        server = HTTPServer(('', 8080), WebServerHandle)
        print("Starting web server on the port 8080..")
        server.serve_forever()
    except KeyboardInterrupt:
        print('^C entered. Shutting down the server..')
        server.socket.close()

if __name__ == '__main__':
    main()

【问题讨论】:

  • 如果你去掉do_POST方法中的try/except,你会发现它和stackoverflow.com/questions/31486618/…是一样的
  • @snakecharmerb 直接代码似乎不起作用,但每当我获得字段值时,我都需要将字段值解码为utf-8,然后即使使用 try catch 块也能正常工作。
  • 删除try/except 块的目的是让实际的错误消息显示在控制台中。然后很容易自己google错误信息。

标签: python python-3.x multipartform-data python-3.6


【解决方案1】:

对表单中的字段值进行了解码。

self.headers.getheader('content-type') 方法更改为

self.headers.('content-type').

然后在之后添加以下行,以解码pdict 值:

pdict['boundary'] = bytes(pdict['boundary'], "utf-8"),

然后通过将字节转换为字符串来打印字段值,我将print 行更改为

print("Restaurant name is ", restaurant_name[0].decode("utf-8")).

所以最终的代码是这样的:

    def do_POST(self):
        try:
            if self.path.endswith("/new"):
                ctype, pdict = cgi.parse_header(self.headers['content-type'])
                pdict['boundary'] = bytes(pdict['boundary'], "utf-8")
                if ctype == 'multipart/form-data':
                    fields = cgi.parse_multipart(self.rfile, pdict)
                    print("Fields value is", fields)
                    restaurant_name = fields.get('newRestaurantName')
                    print("Restaurant name is ", restaurant_name[0].decode("utf-8"))
                    self.send_response(301)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Location', '/restaurant')
                    self.end_headers()
        except:
            print("Inside the exception block")

【讨论】:

    【解决方案2】:

    当我运行你的最终代码时,同样的问题再次发生“本地主机没有发送任何数据”。

    你必须在下面添加content_len = int(self.headers.get('Content-length')) ctype, pdict = cgi.parse_header(self.headers['content-type'])。然后,您需要在pdict['boundary'] = bytes(pdict['boundary'], "utf-8") 下方添加pdict['CONTENT-LENGTH'] = content_len。还有一个缩进错误。

    最终代码:

    from http.server import BaseHTTPRequestHandler, HTTPServer
    import cgi
    
    
    class WebServerHandle(BaseHTTPRequestHandler):
        def do_GET(self):
            try:
                if self.path.endswith("/new"):
                    self.send_response(200)
                    self.send_header('Content-type', 'text/html')
                    self.end_headers()
                    output = ""
                    output += "<html><head><style>body {font-family: Helvetica, Arial; color: #333}</style></head>"
                    output += "<body><h2>Add new Restaurant</h2>"
                    output += "<form method='POST' enctype='multipart/form-data' action='/new'>"
                    output += "<input name='newRestaurantName' type='text' placeholder='New Restaurant Name'> "
                    output += "<input type='submit' value='Add Restaurant'>"
                    output += "</form></html></body>"
                    self.wfile.write(bytes(output, "utf-8"))
                    return
                if self.path.endswith("/restaurant"):
                    self.send_response(200)
                    self.send_header('Content-type', 'text/html')
                    self.end_headers()
                    output = ""
                    output += "<html><head><style>body {font-family: Helvetica, Arial; color: #333}</style></head>"
                    output += "<body><h3>Restaurant name added successfully!</h3>"
                    output += "</html></body>"
                    self.wfile.write(bytes(output, "utf-8"))
                    return
            except IOError:
                self.send_error(404, 'File Not Found: %s' % self.path)
    
        def do_POST(self):
            try:
                if self.path.endswith("/new"):
                    ctype, pdict = cgi.parse_header(self.headers['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)
                        print("Fields value is", fields)
                        restaurant_name = fields.get('newRestaurantName')
                    self.send_response(301)
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Location', '/restaurant')
                    self.end_headers()
    
            except:
                print("Inside the exception block")
    
    
    def main():
        try:
            server = HTTPServer(('', 8080), WebServerHandle)
            print("Starting web server on the port 8080..")
            server.serve_forever()
        except KeyboardInterrupt:
            print('^C entered. Shutting down the server..')
            server.socket.close()
    
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      猜你喜欢
      • 2019-04-18
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 2016-08-22
      相关资源
      最近更新 更多