Python 本地服务器问题:通过 ajax 发布时 rfile 被截断

Python local server issue: rfile gets truncated when posting through ajax

我在通过 Ajax POST 接收到本地 python http.server.

的大字符串时遇到问题

我正在尝试创建一个在本地主机上运行的网络应用程序。 Web 应用程序在启动时加载一个 JSON 文件,并使用它来将数据加载到应用程序中。这些数据最终在使用该应用程序时被操纵。

保存时,我想将整个修改后的数据发送到python脚本,然后将该数据写入上述JSON文件,所以当webapp re-opens,它将包含最新数据。

服务器工作正常,将较小的数据保存到其他文件也没有任何问题。问题是由于我要保存的数据的大小。将数据(作为 JSON.stringified 字符串)发送到 python 脚本时,字符串被截断,因此 python 脚本无法解析它以重新创建 JSON object.

我修改了do_POST函数为returncontent-lengthheader然后实际收到的数据大小:

    def do_POST(self):
      length = int(self.headers['Content-Length'])
      print(length)
      post_data = self.rfile.read(length)
      print(len(post_data))

浏览器发送un-modified数据时,Content-lengthheader为1013727,但rfile长度只有23684

我打印了 rfile 数据,事实上,它不是我尝试发送的整个字符串,而是停在了数组的中间。

我使用 Chrome 开发工具进行了检查,请求负载也是我预期的完整字符串,所以我假设问题可能出在 http.server。不幸的是,我找不到任何关于这可能是什么或如何更改它的信息。

我正在使用 Python 3.4 和 Google Chrome 作为我的浏览器。

如有任何帮助,我们将不胜感激。谢谢!

我通过挖掘套接字和 http.server 代码

创建了一个解决方法

对于 CGIHTTPRequestHandler(在 http.server 中),启用了 rfile 的缓冲,然后第一个缓冲区之后的所有内容似乎都被丢弃了。

我所做的(我认为)是禁用缓冲,然后通过将以下代码添加到处理程序 class:[=11= 来将 "first buffer" 值设置为整个字符串]

rbufsize = -1

def do_POST(self):
  self.rfile._sock = self.rfile
  return CGIHTTPRequestHandler.do_POST(self)

所以它暂时有效,但将来可能会出现问题

我在使用 Python 3.4 + Chrome 时也遇到了同样的问题。错误也出现在 IE 和 Firefox 中。

我修改了它:

# Make rfile unbuffered -- we need to read one line and then pass
# the rest to a subprocess, so we can't use buffered input.
#rbufsize = 0
rbufsize = -1

并注释掉:

# throw away additional data [see bug #427345]
##            while select.select([self.rfile._sock], [], [], 0)[0]:
##                if not self.rfile._sock.recv(1):
##                    break

问题似乎是 rfile 缓冲,而 POST 使用 CGI 的数据很大...

不知道为什么...我在 python 错误数据库中打开了一个新条目。

感谢以上回复,我根据自己的需要调整了答案。 这是对我有用的解决方法:

  def do_POST(self):
        content_length = int(self.headers["content-length"])
        data = ''
        while len(data) < content_length:  # Bypass to read the buffer
            data += self.rfile._sock.read(content_length - len(data))
        data = data.decode('utf-8')