首页 > 解决方案 > 前端的 Gzip - 相当于 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;
}

但是输出不一样。怎么了 ?

标签: javascriptnode.jsgzip

解决方案


您错误地使用了 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 https://stackoverflow.com/a/9458996/7448536
  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。如果这是一个问题,那么只需bytes[9] = 0x0a;在第 3 行之后添加。


推荐阅读