我正在尝试用 python 编写简单的应用程序,它将使用 POST HTTP 方法向服务器发送一些文本,然后获取包含一些文本的响应。
服务器:
from http.server import *
class MyServer(BaseHTTPRequestHandler):
def do_POST(self):
self.send_response(200)
self.send_header("Content-type","text/plain")
self.end_headers()
print(self.rfile.read().decode("UTF-8"))
self.wfile.write(bytes("TEST RESPONSE", "UTF-8"))
address = ("",8000)
httpd = HTTPServer(address, MyServer)
httpd.serve_forever()
客户:
import http.client
class client:
def __init__(self):
h = self.request("127.0.0.1:8000", "POST", "OH YEA")
resp = h.getresponse()
print(resp.status)
#data = resp.read()
def request(self, host, metoda, strona):
headers = { "Host" : host, "Accept": r"text/plain" }
h = http.client.HTTPConnection(host)
h.request(metoda,"",strona,headers)
return h
a = client()
只要行 data = resp.read() 保持注释,一切正常(服务器获取请求打印到它的控制台正文并发送响应),但是当我尝试读取响应正文时,服务器不会打印请求正文我没有得到,即使我得到响应状态 200,我也无法读取响应正文(整个应用程序“挂起”)。我究竟做错了什么?我猜测服务器的行为与未完成的响应处理有关,但我无法完成它,因为我无法获取响应正文。
最佳答案
您的 HTTP 响应中缺少 Content-Length
header 。 HTTP 客户端不知道响应何时完成,因此它会继续等待更多内容。:
def do_POST(self):
content = bytes("TEST RESPONSE", "UTF-8")
self.send_response(200)
self.send_header("Content-type","text/plain")
self.send_header("Content-Length", len(content))
self.end_headers()
print(self.rfile.read().decode("UTF-8"))
self.wfile.write(content)
这还不能完全起作用:服务器也有同样的问题:它只是继续从 rfile
中读取。
def do_POST(self):
content = bytes("TEST RESPONSE", "UTF-8")
self.send_response(200)
self.send_header("Content-type","text/plain")
self.send_header("Content-Length", len(content))
self.end_headers()
print(self.rfile.read(int(self.headers['Content-Length'])).decode("UTF-8"))
self.wfile.write(content)
使用curl,效果很好:
$ curl -X POST http://localhost:8000 -d 'testrequest'
TEST RESPONSE
有多种方法可以在没有 Content-Length
header 的情况下执行此操作,但对于开始来说,这应该足够了。
编辑:这是编写 HTTP 客户端/服务器的一个很好的练习,但对于生产使用,您可能需要考虑更高级的抽象,例如 requests对于客户端和 WSGI或服务器端的完整 Web 框架(Flask 或 Django 是流行的选择,具体取决于您的要求)。
关于python - 无法从 POST 请求 python 获取响应正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20689958/