【问题标题】:I want to decompress a GZIP string with JavaScript我想用 JavaScript 解压缩 GZIP 字符串
【发布时间】:2021-11-09 17:26:37
【问题描述】:

我有这个 GZIPed 字符串:H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==

我用这个网站创建了这个:http://www.txtwizard.net/compression

我尝试使用pako 解压缩它。

import { ungzip } from 'pako';

const textEncoder = new TextEncoder();
const gzipedData = textEncoder.encode("H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==");
console.log('gzipeddata', gzipedData);
const ungzipedData = ungzip(gzipedData);
console.log('ungziped data', ungzipedData);

问题是 Pako 抛出错误:incorrect header check

我在这里错过了什么?

A JSbin

【问题讨论】:

    标签: javascript gzip pako


    【解决方案1】:

    这个字符串是base64编码的。

    您首先需要将其解码为缓冲区:

    const gzippedString = 'H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==';
    const gzippedBuffer = new Buffer(gzippedString, 'base64');
    

    然后你可以解压缩它:

    const unzippedBuffer = ungzip(gzippedBuffer);
    

    ungzip 上的结果是 Unit8Array。如果要将其转换回字符串,则需要再次对其进行解码:

    const unzippedString = new TextDecoder('utf8').decode(unzipped);
    

    【讨论】:

      【解决方案2】:

      "H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==" 是 base64 编码的字符串,您首先需要将其解码到缓冲区中。

      textEncoder.encode 只是将 base64 编码的字符串编码为字节流。

      如何做到这一点取决于你是在浏览器中还是在 nodejs 上。

      node.js 版本

      要将解压缩的数据转换为字符串,您还可以使用new TextDecoder().decode()

      对于节点,您将使用Buffer.from(string, 'base64') 来解码base64 编码的字符串:

      import { ungzip } from 'pako';
      
      // decode the base64 encoded data
      const gzipedData = Buffer.from("H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==", "base64");
      
      console.log('gzipeddata', gzipedData);
      const ungzipedData = ungzip(gzipedData);
      
      
      console.log('ungziped data', new TextDecoder().decode(ungzipedData));
      
      

      浏览器版本

      在浏览器中,您必须使用atob,并且您需要使用例如将解码数据转换为Uint8ArrayUint8Array.from.

      我使用的转换取自 Convert base64 string to ArrayBuffer,您可能需要验证它是否真的适用于所有情况。

      // decode the base64 encoded data
      const gezipedData = atob("H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==")
      const gzipedDataArray = Uint8Array.from(gezipedData, c => c.charCodeAt(0))
      
      console.log('gzipeddata', gzipedDataArray);
      const ungzipedData = pako.ungzip(gzipedDataArray);
      
      
      console.log('ungziped data', new TextDecoder().decode(ungzipedData));
      <script src="https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.4/pako.min.js"></script>

      【讨论】:

      • 现在我得到:invalid stored block lengths
      • @petur 您在哪里运行该代码(浏览器或节点,节点的版本或浏览器)。第一个代码在node 中运行良好,第二个代码在我在浏览器中运行时显示正确的输出。
      • 我在浏览器中运行它。 !我刚刚用atob 替换了Buffer.from,没有意识到我必须同时做atobUint8Array.from 谢谢!
      • @petur 第一个是节点版本(节点有Buffer.from)。第二个是浏览器,只有atob存在,结果调用与pako不兼容,你需要先将其转换为Uint8Array
      猜你喜欢
      • 1970-01-01
      • 2011-08-18
      • 2011-04-07
      • 1970-01-01
      • 2015-02-06
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多