【发布时间】:2016-11-15 07:50:40
【问题描述】:
我在 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,这表明在解析图像时:
- 需要将响应类型设置为blob。所以这段代码就是这样做的。
- 有一条奇怪的线,我根本不知道它在做什么:
String.fromCharCode.apply(null, new Uint8Array(blob))。
因为我对二进制格式一无所知,所以我猜想,可能是愚蠢的,制作 PDF base64 与制作一些随机图像格式 base64 是一样的。因此,按照良好的 SO 传统,我复制了我不太了解的代码。分阶段。
代码的版本 2 只是将响应类型设置为 blob,但没有尝试第二次转换。并且代码有效,并记录了一些看起来像 base64 字符串,但 明显不正确 的字符串。总的来说,它记录了:
W29iamVjdCBCbG9iXQ==
这简直是大错特错。对于 46k 的 pdf 文件来说,它显然太短了,而且我从命令行使用 python 创建的参考 base64 编码要长得多,正如人们所期望的那样。
代码的第 3 版还应用了使用 stringFromCharCode 和所有其他部分的神秘转换,我将其推送到 transform 函数中。
但是,这根本不会记录任何内容 --- 一个空白行出现在控制台的适当位置。没有错误,没有废话输出,只有一个空行。
我知道我从之前的测试中得到了正确的文件。此外,记录原始响应对象的调用会生成 Blob {size: 45587, type: "application/pdf"},这是我正在试验的 pdf 的正确文件大小,因此 blob 实际上包含它进入浏览器时应该包含的内容。
我正在使用并且只需要支持当前版本的 chrome。
谁能告诉我我做错了什么?
谢谢!
【问题讨论】:
标签: javascript google-chrome pdf binary base64