【问题标题】:Gzip in frontend - equivalent to node-gzip前端的 Gzip - 相当于 node-gzip
【发布时间】:2021-02-01 14:38:40
【问题描述】:

假设我在 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.gzip 返回一个 Uint8Array,在其上调用 btoa 将首先将该 Uint8Array 转换为其字符串表示形式:0 到 255 之间的一系列数字,以逗号分隔,然后将该字符串转换为其 b64 表示形式。这根本不是您想要的,您希望将实际字节转换为它们的 base64 表示。看看stackoverflow.com/questions/12710001/… 做正确的事

标签: javascript node.js gzip


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 2016-05-09
    • 2011-08-15
    • 2013-01-19
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    相关资源
    最近更新 更多