Python HTTP 服务器在POST请求时无响应

6 投票
1 回答
8387 浏览
提问于 2025-04-18 00:54

我想用Python搭建一个HTTP服务器,来托管我的网站。我已经实现了do_GET()方法,它运行得很好。但是当我尝试使用POST方法时,服务器没有反应,直到我刷新页面。然后它才开始处理POST请求,但发现连接已经断开了。之后,它就处理GET请求(因为我刷新了页面),然后继续正常运行。

我在客户端使用了jQuery,但我也试过用HTML表单。即使我在另一个浏览器中打开页面,情况也没有改变,所以这肯定是服务器端的问题。

这是客户端的JavaScript代码:

function Send()
        {
            jQuery.post("address", "Blah!", function (data) {
                //get response
                alert(data);
            });
        }

这是服务器的代码(我使用的是Python 3.3.4):

class MyHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
    def do_POST(self):
        print("Data: " + str(self.rfile.read(), "utf-8")) #show request

        response = bytes("This is the response.", "utf-8") #create response

        self.send_response(200) #create header
        self.send_header("Content-Length", str(len(response)))
        self.end_headers()

        self.wfile.write(response) #send response

这是服务器的日志:

10.175.72.200 - - [01/Apr/2014 19:11:26] "GET / HTTP/1.1" 200 -
Data: Blah!
10.175.72.200 - - [01/Apr/2014 19:11:47] "POST /address HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('10.175.72.200', 2237)
Traceback (most recent call last):
  File "C:\Python33\lib\socketserver.py", line 306, in _handle_request_noblock
    self.process_request(request, client_address)
  File "C:\Python33\lib\socketserver.py", line 332, in process_request
    self.finish_request(request, client_address)
  File "C:\Python33\lib\socketserver.py", line 345, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "C:\Python33\lib\socketserver.py", line 666, in __init__
    self.handle()
  File "C:\Python33\lib\http\server.py", line 400, in handle
    self.handle_one_request()
  File "C:\Python33\lib\http\server.py", line 388, in handle_one_request
    method()
  File "C:\Users\Jirek\Desktop\Server\server.py", line 45, in do_POST
    self.wfile.write(response) #send response
  File "C:\Python33\lib\socket.py", line 317, in write
    return self._sock.send(b)
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
----------------------------------------
10.175.72.200 - - [01/Apr/2014 19:11:47] "GET / HTTP/1.1" 200 -

你可以看到,第一行是经典的GET请求。然后我从浏览器调用POST请求,但在刷新之前什么都没有发生。到那时,服务器才开始写日志的其余部分。

1 个回答

12

问题解决了!问题出在代码加载接收到的数据的那一行(在 do_POST() 里)。我只需要指定要读取的数据量。

所以,不要使用 rfile.read(),而是用 rfile.read(numberOfBytes)。POST消息的大小保存在头信息里:numberOfBytes = int(self.headers["Content-Length"])

修复后的方法:

def do_POST(self):
    length = int(self.headers["Content-Length"])
    print("Data: " + str(self.rfile.read(length), "utf-8"))

    response = bytes("This is the response.", "utf-8") #create response

    self.send_response(200) #create header
    self.send_header("Content-Length", str(len(response)))
    self.end_headers()

    self.wfile.write(response) #send response

撰写回答