【问题标题】:Python: BaseHTTPRequestHandler - Read raw postPython:BaseHTTPRequestHandler - 阅读原始帖子
【发布时间】:2013-07-26 18:28:20
【问题描述】:

如何阅读原始 http 帖子字符串。我已经找到了几种阅读帖子解析版本的解决方案,但是我正在处理的项目提交了一个没有标题的原始 xml 有效负载。所以我试图找到一种方法来读取帖子数据而不将其解析为 key => value 数组。

【问题讨论】:

    标签: python httpserver basehttpserver basehttprequesthandler


    【解决方案1】:

    self.rfile.read(int(self.headers.getheader('Content-Length'))) 将原始 HTTP POST 数据作为字符串返回。

    分解:

    1. 标头“Content-Length”指定 HTTP POST 数据包含多少字节。
    2. self.headers.getheader('Content-Length') 以字符串形式返回内容长度(标头的值)。
    3. 在将其作为参数传递给self.rfile.read() 之前,必须将其转换为整数,因此请使用int() 函数。

    另外,请注意标题名称区分大小写,因此必须仅指定为“Content-Length”。

    编辑:显然标头字段不区分大小写(至少在 Python 2.7.5 中),我认为这是自 https://www.rfc-editor.org/rfc/rfc2616 状态以来的正确行为:

    每个标题字段由 名称后跟冒号 (":") 和字段值。字段名称 不区分大小写。

    【讨论】:

    • 请详细一点,我不知道你在暗示什么。
    • @jb:我在答案中添加了更多细节。让我知道是否还有任何具体需要详细说明。
    • @SindhuriKuppasad,标题名称不区分大小写。以下语句都返回我的测试中的内容长度:self.headers.getheader('content-length')self.headers.getheader('content-LENGTH')
    • @famzah,这很有趣。我不记得我在写这个答案时使用的是哪个版本的 Python,但是这个案例很重要,这就是我把答案放在首位的原因。我现在检查了 2.7.5,你是对的,大小写无关紧要。
    • 在 python3 中为self.headers.get('content-length')
    【解决方案2】:

    我认为self.rfile.read(self.headers.getheader('content-length')) 应该将原始数据作为字符串返回。 根据 BaseHTTPRequestHandler 类中的文档:

    - rfile is a file object open for reading positioned at the
    start of the optional input data part;
    

    【讨论】:

    • 在尝试并进行了一些快速的谷歌搜索后,此操作会阻止我和其他人的执行。
    • 需要提供内容长度:data = self.rfile.read(int(self.headers.getheader('content-length')))
    • 是的,对不起。它是阻塞的,因为 rfile 对象是一个套接字,调用 read() 基本上是在说“读取直到没有什么可读取”,但只要套接字打开,还有更多要读取的内容,所以它挂起并等待传入​​的内容。服务器通过始终指定要读取多少内容来避免挂起。对不起,我应该把它放在首位。
    • 在 Python 3.5 中,您需要使用“get”而不是“getheader”。
    • 没有“content-length”标头时会发生什么?您的服务器刚刚崩溃?
    【解决方案3】:

    对于 python 3.7,以下对我有用:

    rawData = (self.rfile.read(int(self.headers['content-length']))).decode('utf-8')
    

    借助此问题中的其他答案以及thisthis。最后一个链接实际上包含完整的解决方案。

    【讨论】:

    • @JulesG.M.这就是我在我提供的最后一个链接中找到的。 utf-8 也适用于我从服务器端作为原始数据读取的内容。如果服务器端返回它以任何其他格式编码,则该值也需要更改以进行解码。
    【解决方案4】:

    io.BufferedIOBase 对象上的 read() 方法一直读取到 EOF。并非所有浏览器都发送 EOF 字符 (source)。读取 Content-Length 字节是一个很好的解决方案。使用read1() 方法也对我有用。它在单个非阻塞 API 调用中尽可能多地读取。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2011-07-16
      • 1970-01-01
      相关资源
      最近更新 更多