如何在接下来的 13 中正确发送 blob 或文件作为 api 响应

问题描述 投票:0回答:1

我正在尝试发送一个 blob(将来将是来自另一个 API 的文件)作为 next13 api 路由中 api 调用的响应。我的处理程序是这样的:

export default async function handler(req, res) {
  const endpoint = `${process.env.UI_ENGINE}/docs/${req.query.id}/download-doc`;

  
    const response = await fetch(endpoint, {
       headers: { Authorization: `${req.headers.authorization}` },
    });

    const blob = await response.blob();
 

    console.log("»»»»»» [DEBUG : blob ] -- :", blob); // Blob { size: 1545, type: 'application/json' }

    res.status(response.status).send(blob);
}

我从我的组件中调用这个 api,例如:

const fetchWithToken = async (service, token) => {
// data fetch function in UI.
    const response = await fetch(`${process.env.basePath}/${service}`, {
      headers: { Authorization: `Bearer ${token}` },
    });

    const blob = await response.blob();

    console.log("»»»»»» [DEBUG : response ] --  :", blob); // Blob {size: 2, type: 'application/json'}

// download as file logic ....
}

正如您所见,ui 数据获取响应中的 blob 给出的 blob 大小为 2(内容将是一个空对象),即使预期大小更大。

我尝试将 blob 转换为可读流并将其从下一个 api 发送回 ui。还尝试利用

File()
。两个想法都失败了。 我能够在 api (
blob.text()
) 中将 blob 转换为文本并将其作为响应发送;但它仅适用于 json、csv 等文件。但范围很广。

我正在使用 nextjs - 13.5.4 节点 - 18.17.1.

我更愿意将文件从

UI_ENGINE
直接发送到前端。请帮助我找到最好的解决方案。预先感谢...

javascript node.js blob next.js13 nextjs-api-router
1个回答
0
投票

在 Next.js API 处理函数中,从相应 API 读取响应 blob 后,我尝试将其转换为流、数组缓冲区和文件,以将响应正确发送回读取函数。然而,这些方法都没有奏效。由于我无法查明确切的问题,我尝试将 blob 转换为原始缓冲区并将其作为响应发送,这令人惊讶地有效。

为此,首先将 blob 转换为数组缓冲区 -

const arrayBuffer = await blob.arrayBuffer();
然后使用 arraybuffer 创建新的原始缓冲区 -
const buffer = Buffer.from(arrayBuffer);

由于我要发送文件,因此在响应中包含一些关键标头非常重要

export default async function handler(req, res) {
  const endpoint = `${process.env.UI_ENGINE}/docs/${req.query.id}/download-doc`;

  try {
    const response = await fetch(endpoint, {
      headers: { Authorization: `${req.headers.authorization}` },
    });

    const blob = await response.blob();

    const contentType =
      response.headers.get("content-type") || "application/octet-stream";
    const contentLength = response.headers.get("content-length") || blob.size;

    // converting blob to raw buffer for transferring
    // (other formats including blob was not working)
    const arrayBuffer = await blob.arrayBuffer();
    const buffer = Buffer.from(arrayBuffer);

    res
      .status(200)
      .setHeader("Content-Type", contentType)
      .setHeader("Content-Length", contentLength)
      .send(buffer);
  } catch (error) {
    res.status(500).send({ message: "Error fetching the document", error });
  }
}

我并不期望这是确切的解决方案。必须有更好的方法来做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.