如何在浏览器中正确地将pdf文件转换为base64?

时间:2016-07-12 22:03:18

标签: javascript google-chrome pdf binary base64

我在chrome扩展程序中有以下代码的三个失败版本,它们试图拦截指向pdf文件的链接的单击,获取该文件,将其转换为base64,然后记录它。但是我担心我对二进制格式和编码一无所知,所以我真的很喜欢这个。

var links = document.getElementsByTagName("a");

function transform(blob) {
    return btoa(String.fromCharCode.apply(null, new Uint8Array(blob)));
};

function getlink(link) {
    var x = new XMLHttpRequest();
    x.open("GET", link, true);
    x.responseType = 'blob';
    x.onload = function(e) {
        console.log("Raw response:");
        console.log(x.response);
        console.log("Direct transformation:");
        console.log(btoa(x.response));
        console.log("Mysterious thing I got from SO:");
        console.log(transform(x.response));
        window.location.href = link;
    };

    x.onerror = function (e) {
        console.error(x.statusText);
    };

    x.send(null);
};

for (i = 0, len = links.length; i < len; i++) {
    var l = links[i]
    l.addEventListener("click", function(e) {
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        getlink(this.href);
    }, false);
};

版本1无法调用x.responseType或拨打transform。这是我原始的,天真的实施。它引发了一个错误:“要编码的字符串包含Latin1范围之外的字符。”

在搜索到该错误后,我找到了this prior SO,这表明在解析图片时:

  1. 响应类型需要设置为blob。所以这段代码就是这么做的。
  2. 有一些奇怪的路线,我根本不知道它做了什么:String.fromCharCode.apply(null, new Uint8Array(blob))
  3. 因为我对二进制格式一无所知,所以我猜想,制作PDF base64与制作一些随机图像格式base64相同,可能是愚蠢的。所以,在优秀的SO传统中,我复制了我并不理解的代码。分阶段。

    代码的第2版只是将响应类型设置为blob但没有尝试第二次转换。代码工作,并记录看起来像base64字符串,但明显不正确的字符串。完整地,它记录了:

      

    W29iamVjdCBCbG9iXQ ==

    哪个是错误的。对于一个46k的pdf文件来说显然太短了,我用命令行中的python创建的参考base64编码要长得多,就像人们所期望的那样。

    然后

    代码的第3版也使用stringFromCharCode和其他所有内容进行神秘转换,我将其推入transform函数。

    但是,这根本不会记录任何内容 - 控制台中的适当位置会出现一个空白行。没有错误,没有废话输出,只是一个空行。

    我知道我从之前的测试中得到了正确的文件。此外,记录原始响应对象的调用产生Blob {size: 45587, type: "application/pdf"},这是我正在试验的pdf的正确文件大小,因此blob实际上包含它进入浏览器时的内容。

    我正在使用,只需要支持当前版本的chrome。

    有人能告诉我我做错了吗?

    谢谢!

2 个答案:

答案 0 :(得分:1)

如果您只需要支持现代浏览器,那么您还应该能够使用FileReader#readAsDataURL

那会让你做这样的事情:

var reader  = new FileReader();
reader.addEventListener("load", function () {
  console.log(reader.result);
}, false);
// The function accepts Blobs and Files
reader.readAsDataURL(x.response);

这会记录data URI,其中包含您的base64数据。

答案 1 :(得分:0)

我想我找到了自己的解决方案。响应类型必须为arraybuffer而不是blob