【问题标题】:Decompress gzip and zlib string in javascript在 javascript 中解压 gzip 和 zlib 字符串
【发布时间】:2013-01-15 06:12:10
【问题描述】:

我想从 tmx 文件中获取压缩层数据。谁知道在 javascript 中解压缩 gzip 和 zlib 字符串的库?我尝试zlib,但它对我不起作用。例如,tmx 文件中的图层数据为:

  <data encoding="base64" compression="zlib">
       eJztwTEBAAAAwqD1T20JT6AAAHgaCWAAAQ==
  </data>

我的javascript代码是

var base64Data = "eJztwTEBAAAAwqD1T20JT6AAAHgaCWAAAQ==";
var compressData = atob(base64Data);
var inflate = new Zlib.Inflate(compressData);
var output = inflate.decompress();

它运行时显示消息错误“不支持的压缩方法”。但是我尝试使用在线工具解压缩为http://i-tools.org/gzip,它返回正确的字符串。

【问题讨论】:

  • 感谢您的提问(即使将压缩数据编码为 base64 似乎有点反常,因为 base64 是一种负压缩格式;我可以看到应用程序...)

标签: javascript gzip zlib compression tmx


【解决方案1】:

我可以通过zlib 解决我的问题。我将我的代码修复如下

var base64Data = "eJztwTEBAAAAwqD1T20JT6AAAHgaCWAAAQ==";
var compressData = atob(base64Data);
var compressData = compressData.split('').map(function(e) {
    return e.charCodeAt(0);
});
var inflate = new Zlib.Inflate(compressData);
var output = inflate.decompress();

【讨论】:

  • 我有一个通过网络 url 检索到的普通 JavaScript 字符串中的 zip 文件 - 如何解压缩它以便可以使用其原始的“纯文本”内容?
【解决方案2】:

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/

或者,您可以在发送数组之前对数组进行 base64 编码,因为当以 JSON 或 XML 发送时,数组会占用大量开销。同样解码:

// 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 documentation

【讨论】:

  • html 示例可能无法正常工作,因为未定义pako。 API 可能已经改变,它现在使用require
  • 注意:String.fromCharCode.apply(null, new Uint16Array(data)) 长输入失败(超出最大调用堆栈大小,JavaScript)这应该适用于更长的数组:stackoverflow.com/a/20604561/774398
  • 对于长字符串,请使用var string = new TextDecoder("utf-8").decode(data),如此处所述:stackoverflow.com/questions/8936984/…
  • 我遇到一个问题。当我使用pako解压时,英文是可以的,但是当遇到中文时,中文字符串会变成不可读的代码。我不知道为什么。gzip压缩会删除图表-设置信息??
【解决方案3】:

对于任何使用 Ruby on Rails 的人,他们希望将压缩的编码数据发送到浏览器,然后通过浏览器上的 Javascript 解压缩,我将上述两个出色的答案结合到以下解决方案中。这是我的应用程序控制器中的 Rails 服务器代码,它在通过 @variable 将字符串发送到浏览器之前压缩和编码字符串到 .html.erb 文件:

require 'zlib'
require 'base64'

    def compressor (some_string)
        Base64.encode64(Zlib::Deflate.deflate(some_string))
    end

这是使用 pako.min.js 的 Javascript 函数:

function uncompress(input_field){
    base64data = document.getElementById(input_field).innerText;
    compressData = atob(base64data);
    compressData = compressData.split('').map(function(e) {
        return e.charCodeAt(0);
    });
    binData = new Uint8Array(compressData);
    data = pako.inflate(binData);
    return String.fromCharCode.apply(null, new Uint16Array(data));
}

这是一个对 uncompress 函数的 javascript 调用,它想要对存储在隐藏 HTML 字段中的数据进行解编码和解压缩:

my_answer = uncompress('my_hidden_field');

这是 Rails application.js 文件中调用 pako.min.js 的条目,该条目位于 /vendor/assets/javascripts em> 目录:

//= require pako.min

我从这里得到了 pako.min.js 文件:

https://github.com/nodeca/pako/tree/master/dist

无论如何,一切都在我的最后! :-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多