Python 如何在wsgi应用程序中使用gzip编码?

Python 如何在wsgi应用程序中使用gzip编码?,python,python-3.x,compression,gzip,wsgi,Python,Python 3.x,Compression,Gzip,Wsgi,我正在尝试使用wsgi输出gzip编码的字符串,这是我的尝试,但不幸的是浏览器只解码第一个字符串,有帮助吗 测试1: import zlib def application(environ, start_response): headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')] data = b'\x1f\x8b\x08\x00\x00\x00\x00\x00'

我正在尝试使用wsgi输出gzip编码的字符串,这是我的尝试,但不幸的是浏览器只解码第一个字符串,有帮助吗

测试1:

import zlib

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    data = b'\x1f\x8b\x08\x00\x00\x00\x00\x00'
    data += zlib.compress(b'test')[:-4]
    data += zlib.compress(b'test2')[:-4]
    headers.append(('Content-Length', str(len(data))))
    start_response('200 OK',headers)
    return [data]
测试2:

import zlib

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    data = b'\x1f\x8b\x08\x00\x00\x00\x00\x00'
    data += zlib.compress(b'test')
    data += zlib.compress(b'test2')
    headers.append(('Content-Length', str(len(data))))
    start_response('200 OK',headers)
    return [data]
测试3:

import zlib

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    start_response('200 OK',headers)
    yield b'\x1f\x8b\x08\x00\x00\x00\x00\x00'
    yield zlib.compress(b'test')[:-4]
    yield zlib.compress(b'test2')[:-4]
测试4:

import zlib

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    start_response('200 OK',headers)
    yield b'\x1f\x8b\x08\x00\x00\x00\x00\x00'
    yield zlib.compress(b'test')
    yield zlib.compress(b'test2')
测试5:

import gzip

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    start_response('200 OK',headers)
    yield gzip.compress(b'test')
    yield gzip.compress(b'test2')

我认为问题在于:

 gzip.compress(b'test')
返回带有

 header  content  THE END 
在里面

这意味着,当您读取它时,解压缩将只返回b“test”。你自己试试看

两种解决方案取决于您想要实现的目标:

  • 创建一个多部分消息。每一份收益都是一份新的文件
  • 压缩
    执行以下操作:

    def compress(data, compresslevel=9):
    
        """Compress data in one shot and return the compressed string.
        Optional argument is the compression level, in range of 0-9.
        """
        buf = io.BytesIO()
        with GzipFile(fileobj=buf, mode='wb', compresslevel=compresslevel) as f:
            f.write(data)
        return buf.getvalue()
    
    执行以下操作:

    import gzip, io
    
    def application(environ, start_response):
        headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding',     'gzip')]
        start_response('200 OK',headers)
        buf = io.BytesIO()
        with GzipFile(fileobj=buf, mode='wb') as f:
             f.write(b'test')
             f.write(b'test2')
        return buf
    
  • 多亏了,这是我自己的解决方案,我使用了它,我想我们不会在这里缓冲太多数据:

    import gzip
    
    class gzipreader:
        def __init__(self):
            self._content = b''
    
        def flush(self):
            pass
    
        def write(self,data):
            self._content += data
    
        def read(self):
            data = self._content
            self._content = b''
            return data
    
    def application(environ, start_response):
        headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
        start_response('200 OK',headers)
        reader = gzipreader()
        writer = gzip.GzipFile(mode='wb',fileobj=reader)
        for s in [b'test', b'test2']:
            writer.write(s)
            #writer.flush()
            yield reader.read()
        writer.close()
        yield reader.read()
    

    那么,问题是什么?为什么test1可以工作,而其他的不能工作?@mockinterface在上面的示例中只解码了第一个,我得到了下面的答案。您不需要实现阅读器。您可以在Python2下使用
    从StringIO导入StringIO作为gzip阅读器,在Python2下使用
    从io导入BytesIO作为gzip阅读器Python3@User它的工作方式不同,我没有输出。对,您可能无法在那里使用read。当您需要内存中的文件时,请记住该模块。很抱歉