我在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,这表明在解析图片时:
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。
有人能告诉我我做错了吗?
谢谢!
答案 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
。