如何在Python中发送和接收HTTP POST请求?

时间:2014-05-05 14:58:47

标签: python http post httplib basehttpserver

我使用这两个Python脚本试图找出如何在Python中发送和接收POST请求:

客户:

import httplib

conn = httplib.HTTPConnection("localhost:8000")
conn.request("POST", "/testurl")
conn.send("clientdata")
response = conn.getresponse()
conn.close()

print(response.read())

服务器:

from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer

ADDR = "localhost"
PORT = 8000

class RequestHandler(BaseHTTPRequestHandler):        
    def do_POST(self):
        print(self.path)
        print(self.rfile.read())
        self.send_response(200, "OK")
        self.end_headers()
        self.wfile.write("serverdata")

httpd = HTTPServer((ADDR, PORT), RequestHandler)
httpd.serve_forever()

问题是服务器在self.rfile.read()上挂起,直到在客户端上调用conn.close()但是如果在客户端上调用conn.close(),则客户端无法从客户端接收响应服务器。这会产生一种情况,即可以从服务器获取响应或读取POST数据但不能同时读取。我假设我在这里缺少一些可以解决这个问题的东西。

其他信息:

conn.getresponse()会导致客户端挂起,直到从服务器收到响应。在服务器上的功能完成执行之前,似乎没有收到响应。

2 个答案:

答案 0 :(得分:4)

您的原始示例存在一些问题。首先,如果您使用request方法,则应该在该调用中包含要发送的邮件正文,而不是单独调用send。文档说明send()可以用作替代request

  

作为使用上述request()方法的替代方法,您   也可以使用这四个功能一步一步地发送您的请求   下方。

您只需要conn.request("POST", "/testurl", "clientdata")

第二个问题是您尝试阅读发送到服务器的内容的方式。 self.rfile.read()尝试读取来自客户端的整个输入流,这意味着它将阻塞直到流关闭。在连接关闭之前,流不会被关闭。你想要做的是准确读取从客户端发送的字节数,以及它。你怎么知道这是多少字节?标题当然是:

length = int(self.headers['Content-length'])
print(self.rfile.read(length))

如果您要做的不仅仅是非常基本的测试,我强烈推荐使用python-requests库。我还建议使用比BaseHTTPServer更好的HTTP框架/服务器来进行非常基本的测试(烧瓶,瓶子,龙卷风等)。

答案 1 :(得分:1)

很长时间回答但在搜索过程中出现了所以我带来了另一个答案。为了防止服务器保持流打开(导致永远不会发送响应),您应该使用 self.rfile.read1() 而不是 self.rfile.read()