【问题标题】:GZip decompression in JavaScript with offset带有偏移量的 JavaScript 中的 GZip 解压缩
【发布时间】:2020-11-10 00:36:10
【问题描述】:

我尝试使用的 API 正在返回 base64 编码响应。响应首先使用具有 4 位偏移量的 GZip 压缩,然后进行 base64 编码。我尝试使用 JavaScript(pakozlib)解析响应,在这两种情况下,它都失败了。 API 有一个 C# 代码示例,说明响应解压缩应如何工作,但我真的不知道如何将其转换为 JavaScript。那么谁能帮我把这个函数转换成 JavaScript 或者只是给我一些关于如何处理 4 字节偏移的提示?我在图书馆的文档中没有找到任何相关内容。

public string Decompress(string value)
{
  byte[] gzBuffer = Convert.FromBase64String(value);
  using (MemoryStream ms = new MemoryStream())
  {
    int msgLength = BitConverter.ToInt32(gzBuffer, 0);
    ms.Write(gzBuffer, 4, gzBuffer.Length - 4);
    byte[] buffer = new byte[msgLength];
    ms.Position = 0;
    using (System.IO.Compression.GZipStream zip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress))
    {
      zip.Read(buffer, 0, buffer.Length);
    }
    return System.Text.Encoding.Unicode.GetString(buffer, 0, buffer.Length);
   }
}

【问题讨论】:

  • 等等,所以一个 unicode 字符串是 gzip'd(使其更小)然后是 base64'd(使其更大),然后在 http 响应中返回(这可能是 gzip'd 代替)?哎呀(osnews.com/story/19266/wtfsm)。
  • zip.Read 不承诺实际读取长度字节,如果您按照他们的示例,您可以创建一个包含一堆尾随零的字符串。
  • @JeremyLakeman 是的,这就是我对他们减压方法的解释......

标签: javascript c# gzip


【解决方案1】:

我将使用fflate(免责声明,我是作者)来执行此操作。如果您想将该功能行翻译为行:

// This is ES6 code; if you want better browser compatibility
// use the ES5 variant.
import { gunzipSync, strToU8, strFromU8 } from 'fflate';
const decompress = str => {
  // atob converts Base64 to Latin-1
  // strToU8(str, true) converts Latin-1 to binary
  const bytes = strToU8(atob(str), true);
  // subarray creates a new view on the same memory buffer
  // gunzipSync synchronously decompresses
  // strFromU8 converts decompressed binary to UTF-8
  return strFromU8(gunzipSync(bytes.subarray(4)));
}

如果你不知道 ES6 是什么:

在您的 HTML 文件中:

<script src="https://cdn.jsdelivr.net/npm/fflate/umd/index.js"></script>

在你的 JS 中:

var decompress = function(str) {
  var bytes = fflate.strToU8(atob(str), true);
  return fflate.strFromU8(fflate.gunzipSync(bytes.subarray(4)));
}

我想提一下,如果您要在最后累积成一个字符串,那么流几乎完全没用,因此 C# 代码不是最理想的。同时,由于您使用的是标准库,因此它是唯一的选择。

此外,我强烈建议尽可能使用回调变体(即gunzip 而不是gunzipSync),因为它在单独的线程上运行以避免导致浏览器冻结。

【讨论】:

    猜你喜欢
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2021-11-30
    • 2017-09-27
    相关资源
    最近更新 更多