解码 Base64 格式的 PDF 文件时出现文件损坏问题

14
有人能解释一下为什么解码Base64会导致PDF损坏吗?我需要找到解码Base64并获取PDF的方法。当我使用此服务时,

https://emn178.github.io/online-tools/base64_decode_file.html

我可以轻松地传递Base64并得到文件,没有问题。

但是当我在node.js中进行相同操作时,我始终获得空(损坏)文件。我尝试了不同的包,例如:js-base64,atob,

但它们都没有起作用,结果仍然是相同的空文件。

代码链接: https://repl.it/@afiliptsov/FaroffGloriousFormula

3个回答

26

因为以下原因,您会得到一个已损坏的PDF文件:

  1. 根据官方文档Base64.decode()函数将Base64值解码为UTF-8字符串。如您所见,这是错误的函数,因为您需要将值解码为二进制数据。
  2. Base64.atob()函数正好符合您的需求,但是您在保存数据时犯了一个错误,因为根据官方文档,默认情况下,fs.writeFile()函数将数据保存为UTF-8编码,而您想要保存二进制数据。

为了正确解码Base64值并将其存储为二进制数据,取决于您的需求,您可以选择以下方法之一:

require('js-base64').Base64.atob()

使用Base64.atob()解码Base64值,并在保存文件时指定二进制编码。仅当您需要处理二进制数据时才有用。与其他方法不同,您必须安装和加载“js-base64”模块。

var bin = Base64.atob(stringToDecode);
// Your code to handle binary data
fs.writeFile('result_binary.pdf', bin, 'binary', error => {
    if (error) {
        throw error;
    } else {
        console.log('binary saved!');
    }
});

Buffer.from

使用Buffer.from()将Base64值转换为缓冲区,并在不指定编码的情况下保存到文件中。只有在需要处理缓冲区时才有用。

var buf = Buffer.from(stringToDecode, 'base64');
// Your code to handle buffer
fs.writeFile('result_buffer.pdf', buf, error => {
    if (error) {
        throw error;
    } else {
        console.log('buffer saved!');
    }
});

编码 选项

如果您不需要读取/修改二进制数据或缓冲区,只需在保存文件时指定编码选项即可。这种方法是最简单的方法,可能也是最快和最节省内存的方法。

fs.writeFile('result_base64.pdf', stringToDecode, 'base64', error => {
    if (error) {
        throw error;
    } else {
        console.log('base64 saved!');
    }
});

你知道.docx有没有特定的格式吗? 对于pdf来说它很好用,但是当我使用docx时,它会提示一个消息并建议我在尝试打开文件时还原文件。 - Anton
1
@Anton 对于Base64来说,它解码的数据类型并不重要。错误只会出现在两种情况下:1)您的Base64字符串已损坏,或者2)您在存储解码结果时犯了错误。由于在您的情况下PDF文件已经正确保存,因此您应该检查第一种情况。也就是说,请确保您的Base64字符串没有损坏,并且与您的文件内容匹配。例如,将docx文件转换为Base64,并将结果与您的字符串进行比较。 - Victor

5

对我来说一个相关的问题是由于阅读了@victor的答案而得以解决。问题在于Express.js应用程序从API获取了一个base64编码的PDF并希望将其作为“正确”的PDF返回给客户端:

res.set({
    'Content-Disposition' : 'attachment; filename='+ data.fileName,
    'Content-Type': 'application/pdf',
});
res.send(Buffer.from(data.content, 'base64'));

3

简单就是最好的! 只需使用fs包将base64字符串保存到文件中,记得要设置encoding选项为base64

fs.writeFile('result_document.pdf', stringToDecode, 'base64', (error) => {
  if (error) throw error;
  console.log("Doc saved!");
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接