使用 Node 在单个响应中发送多个缓冲区

Sending more than one Buffer in a single response with Node

我正在从图像创建两个缓冲区,并希望将它们以单个响应的形式从 Node 服务器发送给客户端。

服务器:

    const response1 = await fetch(imageUrls[0]);
    const response2 = await fetch(imageUrls[1]);
    const arrayBuffer1 = await response1.arrayBuffer();
    const arrayBuffer2 = await response2.arrayBuffer();

    const buffer1 = Buffer.from(arrayBuffer1, "base64");
    const buffer2 = Buffer.from(arrayBuffer2, "base64");

    res.setHeader("Content-Type", "application/json");
    res.send(
      JSON.stringify({
        first: buffer1,
        second: buffer2,
      })
    );

客户:

  fetch(endpoint + new URLSearchParams(paramsObj), {
    method: "GET",
    headers: {
      "Content-type": "application/json",
    },
  })
    .then((response) => {
      const { first, second } = JSON.parse(response.body);
      obv.blob().then((blob) => download(blob));
      rev.blob().then((blob) => download(blob));
    })

问题是 response.body 仍然是一个 ReadableStream 而不是我希望通过 JSON.stringify.

得到的可解析字符串

我还尝试发送包含两个 res.write() 的组合响应,但只收到第一个缓冲区。

如果我仅使用 res.send(buffer1) 从服务器发送 1 个缓冲区,则以下内容有效:

    .then((response) => {
      response.blob().then((blob) => download(blob));
    })

如果您想将缓冲区作为 JSON 发送,您应该考虑将它们转换为 Base64 字符串,然后在响应中发送 JSON object,就像您已经这样做一样正在做。我认为 JSON 格式不支持缓冲区。

const response1 = await fetch(imageUrls[0]);
const response2 = await fetch(imageUrls[1]);

const buffer1 = convertBufferToBase64(response1);
const buffer2 = convertBufferToBase64(response2);

res.setHeader("Content-Type", "application/json");
res.send(
  JSON.stringify({
    first: buffer1,
    second: buffer2,
  })
);

另一种方法是在响应中流式传输缓冲区,在这种情况下,您必须将 Content-Type header 设置为某种二进制格式,例如 application/octet-stream 左右。

const response1 = await fetch(imageUrls[0]);
const arrayBuffer1 = await response1.arrayBuffer();

res.setHeader("Content-Type", "application/octet-stream");
res.send(
  arrayBuffer1
);

就个人而言,我会通过在响应中设置位置 header 和状态代码来重定向客户端以自行获取图像。

const imageUrls = ["blah", "hablo"];
res.setHeader("Location", imageUrls[0]);
res.status(301); //may also use 302 | 303 | 307 | 308
res.end();