在JavaScript中下载PDF blob时出现问题
我创建了一个函数,该函数使用在JavaScript中下载PDF blob时出现问题,javascript,file,download,base64,blob,Javascript,File,Download,Base64,Blob,我创建了一个函数,该函数使用blob和fileName来下载blob,实现如下: const blobToBase64 = (blob, callback) => { const reader = new FileReader(); reader.onloadend = () => { const base64 = reader.result; console.log({ base64 }); callback(base64); }; read
blob
和fileName
来下载blob,实现如下:
const blobToBase64 = (blob, callback) => {
const reader = new FileReader();
reader.onloadend = () => {
const base64 = reader.result;
console.log({ base64 });
callback(base64);
};
reader.readAsDataURL(blob);
};
const downloadFile = (blob, fileName) => () => {
const link = document.createElement('a');
blobToBase64(blob, (base64) => {
link.href = base64;
link.download = fileName;
link.click();
});
};
downloadFile(myBlob, myFileName);
为了尝试调试这个,我制作了一个控制台.log
来注销base64
的值,该值是由reader.result
创建的
base64
值是数据:应用程序/八位字节流;base64,Mzc4MDY4…
我的PDF文件已下载,但已损坏。我在文件下载实现中做错了什么
让我知道是否有任何其他细节,可能有助于这一点?我100%确信blob本身不是一个损坏的文件 我不能肯定为什么你的代码不起作用,但我可以肯定你所做的充其量也没用 不要将Blob转换为dataURI,99%*的时候,您想用这个dataURI做什么可以直接用原始Blob和blobURI来完成 *剩下的1%是当您需要创建包含二进制数据的独立文档时,这种情况会发生,但并不经常发生 在这里,您想做的事情(设置一个锚指向Blob的数据)可以直接用Blob完成:只需通过调用创建一个blobURI(它只是内存中数据的指针)
const downloadFile=(blob,文件名)=>{
const link=document.createElement('a');
//创建一个指向我们的Blob的blobURI
link.href=URL.createObjectURL(blob);
link.download=文件名;
//某些浏览器需要锚定在文档中
document.body.append(link);
link.click();
link.remove();
//以防Blob占用大量内存
setTimeout(()=>URL.revokeObjectURL(link.href),7000);
};
下载文件(新Blob(['random data']),“myfile.txt”)
我尝试使用Fetch API从服务器下载PDF文件,该服务器将八位字节流
内容作为响应。因此,如果您检查响应,您将得到如下字符%PDF-1.4
以下是解决方案:
function download(pdfUrl) {
fetch(pdfUrl).then(resp => resp.arrayBuffer()).then(resp => {
// set the blog type to final pdf
const file = new Blob([resp], {type: 'application/pdf'});
// process to auto download it
const fileURL = URL.createObjectURL(file);
const link = document.createElement('a');
link.href = fileURL;
link.download = "FileName" + new Date() + ".pdf";
link.click();
});
}
在创建blob之前,您可以使用相同的方法对八位字节流的内容进行解码。您的文件类型应该是
application/pdf
,而不是application/octet-stream
将application/octet-stream
替换为application/pdf
并不能修复它。那么您的blob可能就是无效的。你确定它不是吗?我很确定它不是无效的,一直在研究它:/对我来说,你的代码还可以,但我没有使用createObjectURL()两次,只使用一次(请参见const fileURL=…
和link.href=…
行)。我没有尝试上面的双createObjectURL版本,所以我不能说它是否有效not@DanieleCruciani我想你是对的。为了使代码更具可读性,我做了两次。更新了代码。谢谢。我不知道为什么人们会投票给这个答案。他的问题是在javascript中下载PDF blob时出现问题。@SajinMAboobakkar可能是因为这个答案显示了实现这一点的最佳解决方案?无论出于什么原因,iOS对这个实现都很不确定。有人说这是关于合成点击事件的,所以我在页面上创建了一个链接,href是对象URL。这在iOS上的Safari+Firefox上有效,但Chrome没有。有人遇到过这个问题吗?@3stacks,可能是因为在focus中调用了revokeObjectURL,确实使用了更好的解决方案进行了编辑,您能否确认它是否对您有效(我手头没有iOS设备)。@Kaido感谢您这么快的响应,伙计。我添加了revokeObjectURL,得到了一些不同的行为。它实际上在iOS Safari中工作,但iOS Firefox只是在同一窗口中打开blob,iOS Chrome什么也不做。我尝试了几种不同的方法,比如在mount上生成对象URL,然后将其作为href添加到DOM中,后者适用于safari和firefox,但chrome有问题。编辑:老实说,我认为这可能只是iOS的古怪。桌面macOS和android浏览器运行良好。