我目前正在开发的webApp需要客户端请求的大型JSON文件,使用Python构建在服务器上并发送回客户端。该解决方案通过CGI实现,并且在各方面都能正常工作。 在这个阶段,我只是采用各种技术来最小化发送回客户端的大约5-10mb的JSON对象的大小(没有详细说明,这或多或少是固定的,并且不能延迟加载以任何方式)。 我们使用的主机不支持mod_deflate或mod_gzip,因此虽然我们无法将Apache配置为使用.htaccess在服务器上自动创建gzip压缩内容,但我认为我们仍然可以只要正确设置了Content-encoding标头,就可以在客户端接收它并进行解码。
我想知道的是,实现这一目标的最佳途径是什么。在Python中使用Gzipping是微不足道的。我已经知道如何做到这一点,但问题是: 如何以这种方式压缩数据,将其打印到输出流以通过CGI发送将被压缩,并且可以被客户端读取?
必须根据输入数据动态创建文件,因此存储预制文件和预先存档文件不是一种选择,必须通过webApp中的xhr接收它们。
我最初的实验是使用gzip和io.stringIO压缩JSON字符串,然后将其打印到输出流,导致它以Python的正常字节格式打印,例如:b' \ n \ x91 \ x8c \ xbc \ xd4 \ xc6 \ xd2 \ x19 \ x98 \ x14x \ x0f1q!\ xdc | C \ xae \ xe0等等,它将请求膨胀到正常大小的两倍......
我想知道是否有人可以指出我在这方面的正确方向,如果确实可能的话,我将如何实现这一目标。 我希望我能正确地表达我的问题。 谢谢。
答案 0 :(得分:1)
我猜你使用print()
(在将其发送到stdout之前首先将其参数转换为字符串)或sys.stdout
(仅接受str对象)。
要直接在stdout上编写,可以使用sys.stdout.buffer
,这是一个支持字节对象的类文件对象:
import sys
import gzip
s = 'foo'*100
sys.stdout.buffer.write(gzip.compress(s.encode()))
提供有效的gzip数据:
$ python3 foo.py | gunzip
foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo
答案 1 :(得分:0)
感谢Valentin和Phillip的回答! 我设法解决了这个问题,你们两个都为最终答案做出了贡献。事实证明这是一个组合的事情。 这是最终的代码:
response = json.JSONEncoder().encode(loadData)
sys.stdout.write('Content-type: application/octet-stream\n')
sys.stdout.write('Content-Encoding: gzip\n\n')
sys.stdout.flush()
sys.stdout.buffer.write(gzip.compress(response.encode()))
切换到sys.stdout后,而不是使用print打印标题,并刷新它设法正确读取的流。这很奇怪......总是需要学习的东西。 再次感谢!