Gzip 的 JavaScript 实现

IT技术 javascript ajax compression gzip
2021-01-14 12:55:55

我正在编写一个 Web 应用程序,它需要通过 AJAX 将 JSON 数据存储在一个小的、固定大小的服务器端缓存中(想想:Opensocial quotas)。我无法控制服务器。

我需要减少存储数据的大小以保持在服务器端配额内,并希望能够在将其发送到服务器之前在浏览器中对字符串化的 JSON 进行 gzip。

但是,我找不到 Gzip 的 JavaScript 实现方式。关于如何在发送数据之前在客户端压缩数据的任何建议?

6个回答

编辑http://pieroxy.net/blog/pages/lz-string/index.html似乎有更好的 LZW 解决方案可以正确处理 Unicode 字符串(感谢评论中的 pieroxy)。


我不知道任何 gzip 实现,但是jsolait 库(该站点似乎已经消失)具有 LZW 压缩/解压缩功能。该代码包含在LGPL之下

// LZW-compress a string
function lzw_encode(s) {
    var dict = {};
    var data = (s + "").split("");
    var out = [];
    var currChar;
    var phrase = data[0];
    var code = 256;
    for (var i=1; i<data.length; i++) {
        currChar=data[i];
        if (dict[phrase + currChar] != null) {
            phrase += currChar;
        }
        else {
            out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
            dict[phrase + currChar] = code;
            code++;
            phrase=currChar;
        }
    }
    out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
    for (var i=0; i<out.length; i++) {
        out[i] = String.fromCharCode(out[i]);
    }
    return out.join("");
}

// Decompress an LZW-encoded string
function lzw_decode(s) {
    var dict = {};
    var data = (s + "").split("");
    var currChar = data[0];
    var oldPhrase = currChar;
    var out = [currChar];
    var code = 256;
    var phrase;
    for (var i=1; i<data.length; i++) {
        var currCode = data[i].charCodeAt(0);
        if (currCode < 256) {
            phrase = data[i];
        }
        else {
           phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);
        }
        out.push(phrase);
        currChar = phrase.charAt(0);
        dict[code] = oldPhrase + currChar;
        code++;
        oldPhrase = phrase;
    }
    return out.join("");
}
根据维基百科,这些专利几年前就到期了。不过,检查一下可能是个好主意。
2021-03-10 12:55:55
我看到上面的代码至少有两个问题:1)尝试压缩“测试以压缩这个 \u0110\u0111\u0112\u0113\u0114 非 ascii 字符。”,2)如果代码 > 65535,则不会报告错误。
2021-03-16 12:55:55
LZW 太老了,无法获得专利。最后的专利在 2003 年左右用完。有很多免费的实现。
2021-03-27 12:55:55
以下是 21 种不同语言的实现rosettacode.org/wiki/LZW_compression它写的是它从 2004 年开始进入公共领域。
2021-04-03 12:55:55
@some 我刚刚发布了一个小库来纠正你在这里指出的问题:pieroxy.net/blog/pages/lz-string/index.html
2021-04-07 12:55:55

我有另一个问题,我不想在 gzip 中编码数据,而是解码 gzip 数据我在浏览器之外运行 javascript 代码,所以我需要使用javascript对其进行解码

我花了一些时间,但我发现在JSXGraph库中有一种读取 gzip 数据的方法。

这是我找到库的地方:http : //jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/ 甚至有一个独立的实用程序可以做到这一点,JSXCompressor,并且代码是 LGPL 许可的。

只需在您的项目中包含 jsxcompressor.js 文件,然后您就可以读取 base 64 编码的 gzipped 数据:

<!doctype html>
</head>
<title>Test gzip decompression page</title>
<script src="jsxcompressor.js"></script>
</head>
<body>
<script>
    document.write(JXG.decompress('<?php 
        echo base64_encode(gzencode("Try not. Do, or do not. There is no try.")); 
    ?>'));
</script>
</html>

我知道这不是你想要的,但我仍然在这里回复,因为我怀疑它会帮助一些人。

我们需要这个<?php..位吗?我问是因为它被传递给decompress方法。
2021-03-12 12:55:55
我想知道为什么当它是 UNcompressor 时它被称为“compressor”。哈哈
2021-03-15 12:55:55
快5年了,还是有用的。谢谢。我将一个大的 JSON 直接转储到页面,而不是 AJAX。通过用 PHP 预压缩它并将其解压缩回 JavaScript 的客户端 - 我节省了一些开销。
2021-03-18 12:55:55
我明白了 14:16:28.512 TypeError: e.replace is not a function[Weitere Informationen] jsxcompressor.min.js:19:12201
2021-03-25 12:55:55
非常感谢您仍然分享。这正是我所需要的。您可能为我节省了数小时的不成功搜索,而我真的无法节省这些时间。+1
2021-04-09 12:55:55

我们刚刚发布了 pako https://github.com/nodeca/pako,zlib 到 javascript 的端口。我认为这是现在最快的 deflate / inflate / gzip / ungzip js 实现。此外,它还拥有麻省理工学院的民主执照。Pako 支持所有 zlib 选项,其结果是二进制相等的。

例子:

var inflate = require('pako/lib/inflate').inflate; 
var text = inflate(zipped, {to: 'string'});
var inflate = require('pako/lib/inflate').inflate; var text = inflate(zipped, {to: 'string'}); @Redsandro 这是我如何使用 pako。
2021-03-14 12:55:55
请提供用于解码 gzip 字符串的客户端示例。
2021-04-08 12:55:55
那个客户端示例抛出 incorrect header check
2021-04-08 12:55:55

我将 LZMA 的实现从 GWT module移植到独立的 JavaScript 中。它被称为LZMA-JS

你有兼容的 php module吗?
2021-03-10 12:55:55

以下是一些在 Javascript 中实现的其他压缩算法:

这非常接近我想要的。谷歌搜索的东西也会在这里更新
2021-03-14 12:55:55
这个 LZMA 实现需要 BrowserPlus(一个浏览器扩展)并且看起来不是纯 Javascript
2021-03-18 12:55:55
geocities死了,会更新链接
2021-03-25 12:55:55
这个 LZ77 实现不再可用,至少它的 Python 版本(发布在同一页面上)对于非常简单的输入是不正确的。
2021-04-01 12:55:55