ZLIB解压缩-客户端

21

我收到的数据是一个被压缩为 "ZLIB" 格式的输入流。

使用Javascript/Ajax/JQuery,我需要在客户端上解压它。

有没有方法可以做到这一点?

以下是我在JAVA中已经实现的代码,但现在需要在客户端上完成。

url = new URL(getCodeBase(), dataSrcfile); 
URLConnection urlConn = url.openConnection();
urlConn.setUseCaches(false); 
InputStream in = urlConn.getInputStream();
InflaterInputStream inflate = new InflaterInputStream(in);
InputStreamReader inputStreamReader = new InputStreamReader(inflate);
InputStreamReader inputStreamReader = new InputStreamReader(in);
BufferedReader bufReader = new BufferedReader(inputStreamReader);
// Read until no more '#'
int i = 0;
int nHidden = 0;
String line1;
do //------------------------Parsing Starts Here
{
    line1 = bufReader.readLine();
.............
...... so on

1
为什么不直接使用HTTP压缩呢?浏览器会自动透明处理。 - Quentin
2
如果服务器端已经存在且无法更改怎么办?我同意在HTTP级别进行压缩会更好,但你并不总是有选择的余地。 - Codo
你尝试过将zlib C代码编译为Javascript吗?看起来Emscripten可以做到这一点。 - nside
这回答是否解决了你的问题?在 JavaScript 中解压缩 gzip 和 zlib 字符串 - Vladimir Panteleev
9个回答

28

Pako 是一个完整而现代的 Zlib 移植版。

这里有一个非常简单的示例,您可以从中开始。

获取 pako.js,您可以像这样解压缩 byteArray:

<html>
<head>
  <title>Gunzipping binary gzipped string</title>
  <script type="text/javascript" src="pako.js"></script>
  <script type="text/javascript">

    // Get datastream as Array, for example:
    var charData    = [31,139,8,0,0,0,0,0,0,3,5,193,219,13,0,16,16,4,192,86,214,151,102,52,33,110,35,66,108,226,60,218,55,147,164,238,24,173,19,143,241,18,85,27,58,203,57,46,29,25,198,34,163,193,247,106,179,134,15,50,167,173,148,48,0,0,0];

    // Turn number array into byte-array
    var binData     = new Uint8Array(charData);

    // Pako magic
    var data        = pako.inflate(binData);

    // Convert gunzipped byteArray back to ascii string:
    var strData     = String.fromCharCode.apply(null, new Uint16Array(data));

    // Output to console
    console.log(strData);

  </script>
</head>
<body>
    Open up the developer console.
</body>
</html>

运行示例:http://jsfiddle.net/9yH7M/

或者,在将数组作为JSON或XML发送时,您可以先对其进行base64编码,以减少开销。同样地,解码也是如此:

// Get some base64 encoded binary data from the server. Imagine we got this:
var b64Data     = 'H4sIAAAAAAAAAwXB2w0AEBAEwFbWl2Y0IW4jQmziPNo3k6TuGK0Tj/ESVRs6yzkuHRnGIqPB92qzhg8yp62UMAAAAA==';

// Decode base64 (convert ascii to binary)
var strData     = atob(b64Data);

// Convert binary string to character-number array
var charData    = strData.split('').map(function(x){return x.charCodeAt(0);});

// Turn number array into byte-array
var binData     = new Uint8Array(charData);

// Pako magic
var data        = pako.inflate(binData);

// Convert gunzipped byteArray back to ascii string:
var strData     = String.fromCharCode.apply(null, new Uint16Array(data));

// Output to console
console.log(strData);

运行示例:http://jsfiddle.net/9yH7M/1/

如果想更进一步,这里是pako API文档:pako API documentation


感谢您对我的工作示例被投票降低的建设性评论。 - Redsandro
4
要从未压缩的数据中获取字符串,您可以按照以下方式执行:var strData = pako.inflate(binData, { to: 'string' });。请参阅此处的选项:http://nodeca.github.io/pako/#inflate - Julien P

13

1
我宁愿使用有英文文档的库,这个库的自述文件是用某种亚洲语言编写的,看起来像是日语或中文。 - Tener
8
我看不出那有什么关系。如果你熟悉zlib,API就很清楚了。这个库设计得非常好,速度快,而且易于使用。 - user1009908
11
点击标有“英文文档”的链接(https://github.com/imaya/zlib.js/blob/master/README.en.md),即可获取英文文档。 - dotancohen
我使用Pako.js的体验比imaya/zlib.js更好。 - Saran

3

3
尝试使用pako https://github.com/nodeca/pako,它不仅仅是inflate/deflate功能,而且是将zlib精确移植到JavaScript中,并且几乎支持所有特性和选项。此外,它是现代浏览器中最快的实现。

3
已点赞。您能提供一个客户端示例(包括所需的文件)吗?所有文档都是关于使用(服务器端)node.js的。 - Redsandro
这里有一个浏览器示例:https://github.com/nodeca/pako/blob/master/examples/browser.html - thameera

2
正如你问题的第一条评论所建议的那样,我认为你实际上希望浏览器处理解压缩。如果我误解了你的意思,你可以尝试查看JSXGraph库,它应该包含用于deflate和unzip的纯JS实现

谢谢您的回复,但我有点困惑。我查看了JSXGraph,但它似乎是一个绘制弧形、圆形等形状的库。请问您是否有一个纯HTML和JavaScript(不含PHP)的示例,可以解压使用Zlib压缩的文件(输入流)。请帮忙。 - Rajeev Raina

1

使用Pako,您可以解码压缩(gzib)响应,以上述答案的简短代码。

JSON.parse(Pako.inflate(Buffer.from(data, 'base64'), { to: 'string' }))

Buffer.from, Pako

的内容与编程有关。

1

js-deflate 项目由 dankogai 开发,可能是您正在寻找的内容。我实际上还没有尝试过它,但 rawinflate.js 代码似乎相当简洁,并且应该能够解压缩 DEFLATE/zlib 编码的数据。


0

你应该看到zlib rfc

我测试过的 JavaScript 解压代码:在 JavaScript 中解压

我编写的 Java 代码:

    static public byte[] compress(byte[] input) {
    Deflater deflater = new Deflater();
    deflater.setInput(input, 0, input.length);
    deflater.finish();
    byte[] buff = new byte[input.length + 50];
    deflater.deflate(buff);

    int compressedSize = deflater.getTotalOut();

    if (deflater.getTotalIn() != input.length)
        return null;

    byte[] output = new byte[compressedSize - 6];

    System.arraycopy(buff, 2, output, 0, compressedSize - 6);// del head and
                                                                // foot byte
    return output;
}

非常重要的是,在Java中进行deflate操作时,必须剪切掉头部的2个字节和尾部的4个字节,以获取原始的deflate数据。


0

Browserify-zlib 对我来说非常完美,它使用了 pako 并且具有与 zlib 完全相同的 API。在客户端使用 pako 压缩/解压缩 zlib 编码有效载荷的问题上,我曾经苦苦挣扎了数天,但现在我可以毫不犹豫地说 browserify-zlib 真的非常方便。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接