2016-12-05 1327 views
0

使用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')

),但它也引發錯誤。

回答

2
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 <10。 (至少那個很容易填充。) – bobince