用pako压缩(javascript中的zlib),用zlib(python)解压缩不起作用

问题描述:

使用pako在JavaScript中执行压缩的代码(https://github.com/nodeca/pakoPako。它压缩字符串“T”用pako压缩(javascript中的zlib),用zlib(python)解压缩不起作用

var compressedString = pako.gzip('t', {level: 4, to: 'string'})); 
$.ajax('/decompress', {string: compressedString}) 

在该代码/解压缩,做减压

from cgi import parse_qs, escape 
import json 
import zlib 
def application(environ, start_response): 
    status = '200 OK' 
    try: 
     request_body_size = int(environ.get('CONTENT_LENGTH', 0)) 
    except (ValueError): 
     request_body_size = 0 
    request_body = environ['wsgi.input'].read(request_body_size) 
    d = parse_qs(request_body) 

    response_headers = [('Content-type', 'text/plain')] 
    start_response(status, response_headers) 
    inputString = d.get('string')[0] 
    # Use same wbits(=31) as used by pako 
    decompressed = zlib.decompress(inputString, 31); 
    return 'done' 

否则减压引发下面的错误。 zlib.decompress行发生错误。

error: Error -3 while decompressing data: incorrect header check

我还试图编码inputString(

inputString.encode('utf-8')

),但它也引发错误。

to: 'string' 

此选项走私输出字节序列插入到一个JS(Unicode)的String,由每个字节映射到与相同数目的字符。 (这相当于使用ISO-8859-1编码进行解码。)

$.ajax('/decompress', {string: compressedString}) 

XMLHttpRequest的需要的(Unicode)的字符串值编码回一个字节序列去(网址编码的)通过网络。它使用的编码是UTF-8,而不是ISO-8859-1,所以网络上的字节序列将不会与GZip压缩器产生的字节序列相同。

您可以在Python的最终通过重新编码的URL解码步骤之后撤消了这一过程:

d = parse_qs(request_body).decode('utf-8').encode('iso-8859-1') 

现在你应该有走出压缩机的字节顺序相同。

将字节发送为UTF-8编码的码点,并对其中的非ASCII字节进行URL编码,将会使网络流量膨胀至原始字节数的四倍左右,而这相当于取消了压缩的好工作。

如果您只是将数据字符串作为请求主体发布到Python脚本,则可能会丢失URL编码,然后您的请求只会比原始压缩数据多出50%(!)。为了做得更好,你需要开始直接发送原始字节as a ByteArray,或者使用多部分form-data。无论哪种方式都有浏览器兼容性问题。

+0

我不知道iso-8859-1编码。我花了几天时间来解决这个问题。非常感谢:) – hariom

+0

我将研究你提到的由于UTF-8编码而发送3个字节的问题(这在一定程度上压缩了目的)。目前的问题是我需要发送混合数据。有些值不是二进制的,有些是二进制数据。所以,我无法直接设置多部分表单数据标题。 – hariom

+0

第一步可能是尝试使用base64,它只比raw大33%。在大多数浏览器中,你的base64都是['atob()'](https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/atob),但是 - 再次! - 你需要回退IE bobince