【问题标题】:Decode Base64 encoded PDF content in browser在浏览器中解码 Base64 编码的 PDF 内容
【发布时间】:2015-10-09 10:25:23
【问题描述】:

我们在后端 (PHP) 中使用 dompdf 将 HTML 转换为 PDF。 dompdf 生成的输出是 Base64 编码的

$output = $dompdf->output();
base64_encode($output);

此 Base64 编码内容在服务器上保存为文件。当我们像这样解码这个文件内容时:

cat /tmp/55acbaa9600f4 | base64 -D > test.pdf

我们得到一个正确的 PDF 文件。

但是当我们将 Base64 内容作为 JSON 对象内的字符串值传输到客户端时(服务器提供 RESTful API...):

{
  "file_data": "...the base64 string..."
}

并使用 atob() 对其进行解码,然后创建一个 Blob 对象以稍后下载文件,PDF 始终为“空”/损坏。

$scope.downloadFileData = function(doc) {
  DocumentService.getFileData(doc).then(function(data) {
    var decodedFileData = atob(data.file_data);
    var file = new Blob([decodedFileData], { type: doc.file_type });
    saveAs(file, doc.title + '.' + doc.extension);
  });
};

当我们记录解码后的内容时,似乎内容“坏了”,因为有几个符号与我们在服务器上使用base64 -D解码内容时不一样。

当我们对简单文本/纯文档的内容进行编码/解码时,它会按预期工作。但所有二进制(或非 ASCII 格式)都不起作用。

我们已经在网上搜索了很多小时,但没有找到适合我们的解决方案。有没有人有同样的问题,可以为我们提供一个可行的解决方案?提前致谢!

这是一个在服务器上对 PDF 文档进行 Base64 编码内容的示例:

JVBERi0xLjMKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZwovT3V0bGluZXMgMiAwIFIKL1BhZ2VzIDMgMCBSID4 + CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9PdXRsaW5lcyAvQ291bnQgMCA + PgplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMKL0tpZHMgWzYgMCBSCl0KL0NvdW50IDEKL1Jlc291cmNlcyA8PAovUHJvY1NldCA0IDAgUgovRm9udCA8PCAKL0YxIDggMCBSCj4 + CJ4 + Ci9NZWRpYUJveCBbMC4wMDAgMC4wMDAgNjEyLjAwMCA3OTIuMDAwXQogPj4KZW5kb2JqCjQgMCBvYmoKWy9QREYgL1RleHQgXQplbmRvYmoKNSAwIG9iago8PAovQ3JlYXRvciAoRE9NUERGKQovQ3JlYXRpb25EYXRlIChEOjIwMTUwNzIwMTMzMzIzKzAyJzAwJykKL01vZERhdGUgKEQ6MjAxNTA3MjAxMzMzMjMrMDInMDAnKQo + PgplbmRvYmoKNiAwIG9iago8PCAvVHlwZSAvUGFnZQovUGFyZW50IDMgMCBSCi9Db250ZW50cyA3IDAgUgo + PgplbmRvYmoKNyAwIG9iago8PCAvRmlsdGVyIC9GbGF0ZURlY29kZQovTGVuZ3RoIDY2ID4 + CnN0cmVhbQp4nOMy0DMwMFBAJovSuZxCFIxN9AwMzRTMDS31DCxNFUJSFPTdDBWMgKIKIWkKCtEaIanFJZqxCiFeCq4hAO4PD0MKZW5kc3RyZWFtCmVuZG9iago4IDAgb2JqCjw8IC9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMQovTmFtZSAvRjEKL0Jhc2VGb250IC9UaW1lcy1Cb2xkCi9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nCj4 + CmVuZG9iagp4cmVmCjAgOQowMDAwMDAwMDAwIDY1N TM1IGYgCjAwMDAwMDAwMDggMDAwMDAgbiAKMDAwMDAwMDA3MyAwMDAwMCBuIAowMDAwMDAwMTE5IDAwMDAwIG4gCjAwMDAwMDAyNzMgMDAwMDAgbiAKMDAwMDAwMDMwMiAwMDAwMCBuIAowMDAwMDAwNDE2IDAwMDAwIG4gCjAwMDAwMDA0NzkgMDAwMDAgbiAKMDAwMDAwMDYxNiAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDkKL1Jvb3QgMSAwIFIKL0luZm8gNSAwIFIKPj4Kc3RhcnR4cmVmCjcyNQolJUVPRgo = P>

如果你 atob() 这个,你不会得到与在控制台上使用 base64 -D 相同的结果。为什么?

【问题讨论】:

  • 您找到解决方法了吗?我有同样的问题。即使使用外部库...
  • 我们仍然使用浏览器 btoa() 编码为 base64。我们以这种格式将它存储在服务器上,服务器本身解码内容并将其直接流式传输到浏览器。我们无法通过我们的 RESTful API 将其作为 JSON 发送回来并让浏览器对其进行解码。只有文本格式(例如 MIME 类型文本/纯文本)有效,PDF 和其他非可读格式无效。如果您有解决方案,请告诉我,因为我们对我们的解决方法不满意。

标签: javascript json pdf encoding base64


【解决方案1】:

您的问题看起来与我最近需要解决的问题相同。

这对我有用:

const binaryImg = atob(base64String);
const length = binaryImg.length;
const arrayBuffer = new ArrayBuffer(length);
const uintArray = new Uint8Array(arrayBuffer);

for (let i = 0; i < length; i++) {
    uintArray[i] = binaryImg.charCodeAt(i);
}

const fileBlob = new Blob([uintArray], { type: 'application/pdf' });

saveAs(fileBlob, 'filename.pdf');

似乎只做一个base64解码是不够的……你需要把结果放到一个Uint8Array中。否则,pdf 页面显示为空白。

我在这里找到了这个解决方案: https://github.com/sayanee/angularjs-pdf/issues/110#issuecomment-579988190

【讨论】:

    【解决方案2】:

    您可以在某些浏览器中使用btoa()atob() 工作: 例如。

    var enc = btoa("this is some text");
    alert(enc);
    alert(atob(enc));
    

    到JSON和base64是完全独立的。

    Here's a JSON stringifier/parser(和direct GitHub link)。

    Here's a base64 Q&AHere's another one.

    【讨论】:

    • base64 编码在服务器上完成,因为从 HTML 转换为 PDF 涉及一些处理。我知道 btoa() 和 atob() 在 javascript 中是对应的。如上所述,如果对字符串进行编码和解码,一切都会完美运行。但如果是“二进制”内容(在我们的例子中是 pdf 文件的内容),则它不起作用。
    • 我认为这可能对您有所帮助:developer.mozilla.org/en-US/docs/Web/API/WindowBase64/…
    猜你喜欢
    • 2020-03-25
    • 2015-03-21
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 2012-10-27
    • 2011-05-18
    相关资源
    最近更新 更多