简体   繁体   English

NodeJS - 如何在不将文件保存在服务器上的情况下从 Base64 返回 PDF?

[英]NodeJS - How to return a PDF from a Base64 without saving the file on server?

Here is my scenario:这是我的场景:

  • I have an application built in Node with Express;我有一个使用 Express 在 Node 中构建的应用程序;
  • I have an external API that returns a Base64 PDF file;我有一个返回 Base64 PDF 文件的外部 API;
  • I have to get this Base64 and open the file for the user;我必须得到这个 Base64 并为用户打开文件;
  • I am unable to save the PDF on server.我无法在服务器上保存 PDF。

I've tried many ways and I can't open the file to the user.我尝试了很多方法,但无法向用户打开文件。

Ways I've tried:我试过的方法:

const buff = Buffer.from(myBase64, 'base64');
const file = fs.writeFileSync('boleto.pdf', buff, { encoding: 'base64' });

try {
  res.setHeader('Content-Length', file.size);
  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', 'attachment; filename=boleto.pdf');
} catch (e) {
  return res.status(404).send({ error: e, message: 'File does not exist.', statusCode: 404 });
}
const buff = Buffer.from(myBase64, 'base64');
const file = fs.writeFileSync('boleto.pdf', buff, { encoding: 'base64' });

try {
  res.contentType('application/pdf');
  return res.status(200).sendFile('boleto');
} catch (e) {
  return res.status(404).send({ error: e, message: 'File does not exist.', statusCode: 404 });
}
const buff = Buffer.from(myBase64, 'base64');
const file = fs.readFileSync(buff, { encoding: 'base64' });

try {
  res.contentType('application/pdf');
  return res.status(200).sendFile(file);
} catch (e) {
  return res.status(404).send({ error: e, message: 'File does not exist.', statusCode: 404 });
}

Can someone help me?有人能帮我吗?

The proper way to do this here would be to call the service and direct the base64 string response to a decoding stream, then pipe that to the response output.在此处执行此操作的正确方法是调用服务并将 base64 字符串响应定向到解码流,然后将其通过管道传输到响应输出。 That would save you having to wait for files to download or for the string -> byte translation to finish.这将使您不必等待文件下载或string -> byte转换完成。

However if you are only dealing with small files (<1MB) or you dont have to handle traffic from thousands of concurrent requests its probably fine to just download the base64 string and use Buffer.from(base64str, 'base64') to decode it before passing it onwards.但是,如果您只处理小文件 (<1MB) 或者您不必处理来自数千个并发请求的流量,那么只需下载 base64 字符串并使用Buffer.from(base64str, 'base64')进行解码就可以了继续传递它。

This "minimal implementation" approach goes something like this:这种“最小实现”方法是这样的:

const axios = require('axios'); // or any other similar library (request, got, http...)

const express = require('express');
const router = express.Router();

router.get('/invoice/:id.pdf', async (req, res) => {
  // Here is the call to my external API to get a base64 string.
  const id = req.params.id;
  const base64str = await axios.get('https://myfileapi.domain.com/file/?id=' + id);

  // Here is how I get user to download it nicely as PDF bytes instead of base64 string.
  res.type('application/pdf');
  res.header('Content-Disposition', `attachment; filename="${id}.pdf"`);
  res.send(Buffer.from(base64str, 'base64'));
});

module.exports = router;

Note that there is no authentication here to block other users accessing this file, if you want authentication you'll have to handle that separately.请注意,此处没有身份验证来阻止其他用户访问此文件,如果您需要身份验证,则必须单独处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM