您的位置:

解决httputil.HTTPInputError("Response code %d cannot have body" % code)在tornado出现报错

  发布时间:2025-03-14 11:46:31
当tornado遇到HTTP状态码为405、406、408、411、413、415、501或505时,会出现httputil.HTTPInputError的错误,该错误表示响应体不应该被返回,可以通过捕获异常并处理相应状态码避免该错误。解决方法包括确保服务器端返回的状态码与HTTP协议规范相符,客户端处理异常时捕获HTTPInputError异常,以及在使用Tornado的HTTPClient时设置allow_nonstandard_methods等。具体例子演示了如何正确处理HTTPInputError错误。

问题原因

tornado出现httputil.HTTPInputError("Response code %d cannot have body" % code)的原因是HTTP状态码为405、406、408、411、413、415、501或505时,tornado认为其响应体不应该被返回,因为这些状态码通常表示请求有误或服务器无法处理。 为了避免这个错误,可以在处理请求时检查返回的状态码,如果是上述提到的状态码之一,确保不返回响应体即可。可以通过捕获httputil.HTTPInputError异常并在相应的处理逻辑中处理这种情况。 以下是一个处理HTTP状态码为405的示例代码:


import tornado.web
from tornado import httputil

class MainHandler(tornado.web.RequestHandler):
    def post(self):
        try:
            # 处理POST请求
            if some_condition:
                self.set_status(405)  # 设置状态码为405
                self.finish()  # 结束响应,不返回响应体
        except httputil.HTTPInputError as e:
            self.set_status(e.status_code)  # 设置错误状态码
            self.finish()  # 结束响应,不返回响应体

通过以上示例代码,可以在处理POST请求时,如果满足某条件,设置状态码为405并结束响应,避免出现tornado.httputil.HTTPInputError("Response code 405 cannot have body")错误。

解决方案

httputil.HTTPInputError("Response code %d cannot have body" % code) 错误是由于 Tornado 在处理 HTTP 请求时,遇到了一个不能包含响应体的响应状态码(如 204 No Content,304 Not Modified 等)却收到了响应体导致的异常。 要解决这个问题,可以采取以下几种方法: 1. 确保服务器端返回的响应状态码与 HTTP 协议规范相符,不应该在不允许有响应体的状态码中返回响应体。 2. 在客户端处理这种异常情况时,可以捕获 httputil.HTTPInputError 异常,并针对性地处理,比如跳过读取响应体的步骤。 3. 如果是在使用 Tornado 的 HTTPClient 进行请求时出现这个问题,可以在发起请求时设置 allow_nonstandard_methods=True,这样就允许不标准的 HTTP 方法和状态码了。例如:


   client = httpclient.HTTPClient()
   try:
       response = client.fetch("http://example.com", method="SOME_NON_STANDARD_METHOD", allow_nonstandard_methods=True)
       # 处理响应
   except httputil.HTTPInputError as e:
       print("HTTPInputError:", e)
   finally:
       client.close()

通过以上方法的合理运用,可以解决 Tornado 出现 httputil.HTTPInputError("Response code %d cannot have body" % code) 的问题。

具体例子

httputil.HTTPInputError("Response code %d cannot have body" % code) 这个错误表示在收到指定的响应代码时尝试读取正文(body)时出错。一般来说,对于一些特定的响应代码,如 204 No Content,303 See Other 等,根据 HTTP 规范是不应该包含正文的。因此,当试图读取这些响应的正文时,就会触发该错误。 为了正确处理这个错误,你可以在尝试读取响应正文之前,先检查响应的状态码,如果是对应不应该包含正文的响应代码,就不要尝试读取正文。 以下是一个使用 tornado 的示例代码,演示了如何正确处理 httputil.HTTPInputError 错误:


import tornado.ioloop
import tornado.web
from tornado import httpclient
from tornado import httputil

async def fetch_data():
    http_client = httpclient.AsyncHTTPClient()
    try:
        response = await http_client.fetch("https://www.example.com")
        if response.code == 204 or response.code == 303:
            # 对于 204 No Content 和 303 See Other,不尝试读取正文
            print("Response code %d cannot have body" % response.code)
        else:
            body = response.body
            print(body)
    except httputil.HTTPInputError as e:
        print("Caught HTTPInputError:", e)

if __name__ == "__main__":
    tornado.ioloop.IOLoop.current().run_sync(fetch_data)

在这个示例中,我们先尝试获取一个网址的响应,然后根据响应的状态码来决定是否读取响应正文。如果状态码是 204 或 303,就不尝试读取正文,并打印提示信息;如果遇到 httputil.HTTPInputError 错误,则捕获该错误并打印相应的错误信息。 通过以上代码示例,我们可以正确处理 httputil.HTTPInputError 错误,并根据实际情况决定是否读取 HTTP 响应的正文。