前端的 Gzip - 相当于 node-gzip

Gzip in frontend - equivalent to node-gzip

假设我在 NodeJS 中有以下内容:

import {
  gzip
} from "node-gzip";

const samlToken = fs.readFileSync(
  "./localDevToken.txt",
  "utf8",
);

const bufferSamlToken = Buffer.from(
  samlToken.replace("\r\n", ""),
  "utf8",
);

const gZipToken = await gzip(bufferSamlToken);
localDevToken = gZipToken
  .toString("base64")
  .replace(/\+/g, "-")
  .replace(/\//g, "_")
  .replace(/=+$/g, "");

我想在前端做同样的事情。我怎样才能实现它?

这是我使用 https://github.com/nodeca/pako

中的 Pako 库进行的尝试

function convertSamlToken(input) {
  var samlToken = input.replace("\r\n", "");
  samlToken = pako.gzip(samlToken, {
    to: 'string'
  });
  samlToken = btoa(samlToken)
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=+$/g, "");

  return samlToken;
}

但输出不同。怎么了?

你没有正确使用 pako,没有 {to: 'string'} 选项,所以输出是一个 Uint8Array。您的函数应如下所示:

function convertSamlToken(input) {
  const samlToken = input.replace("\r\n", "");
  const bytes = pako.gzip(samlToken);

  // Convert Uint8Array to base64 in a safe way
  // See 
  let binary = "";
  for (let i = 0; i < bytes.byteLength; i++) {
    binary += String.fromCharCode(bytes[i]);
  }

  return btoa(binary)
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=+$/g, "");
}

我已经在随机 UTF-8 数据上测试了这个函数,它产生完全相同的输出,除了第 10 个字节,因为那是 OS ID。这是因为 node-gzip 将其设置为 0x0A/TOPS-20 而 pako 使用 0x03/Unix。如果这是一个问题,那么只需在第 3 行之后添加 bytes[9] = 0x0a;