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

时间:2016-12-05 17:57:49

标签: javascript python unicode utf-8 zlib

使用pako(https://github.com/nodeca/pakoPako在javascript中执行压缩的代码。它会压缩字符串'

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

执行解压缩的/ decompress代码

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行发生错误。

  

错误:解压缩数据时出错-3:错误的标题检查

我也试过编码inputString(

  

inputString.encode(' UTF-8&#39)

)但它也会引发错误。

1 个答案:

答案 0 :(得分:3)

to: 'string'

此选项通过将每个字节映射到具有相同编号的字符,将输出字节序列走私到JS(Unicode)String中。 (这相当于使用ISO-8859-1编码进行解码。)

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

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

您可以通过在URL解码步骤后重新编码来在Python端撤消此过程:

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

现在你应该拥有与压缩器相同的字节序列。

将字节作为UTF-8编码的代码点发送,并对其中的非ASCII字节进行URL编码,这将使网络流量膨胀到原始字节占用的大约四倍,这相当于良好的压缩工作。

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