jsPDF首次生成PDF正常,二次生成无法更新问题求助
二次下载PDF仍为旧文件的问题排查与解决
问题场景
用户选择选项后可下载生成的PDF,修改选项后再次下载,得到的仍是首次生成的旧PDF。尝试将doc变量设为null清除实例无效,生成PDF的代码如下:
$(".button").click(function(){ var doc = new jsPDF('landscape'); doc.addImage(frontImg, 'PNG', 0, 0, 300, 210); doc.addPage('a6','l'); doc.addImage(backImg, 'PNG', 0, 0, 300, 210); doc.save('file.pdf'); });
其中frontImg和backImg为dataURI格式图片,疑问是为何更新这两个变量后,PDF内容未同步更新。
核心原因分析
每次点击事件都会新建jsPDF实例,所以doc变量的状态不会影响下一次生成。问题出在两个方向:
frontImg/backImg变量未真正更新:修改选项的逻辑可能没有正确覆盖这两个变量的值;- 浏览器缓存了dataURI图片:浏览器会对重复的dataURI内容进行缓存,即使变量看似更新,实际渲染时仍会调用缓存的旧图片。
排查与解决方法
第一步:确认变量是否真的更新
在点击事件中添加日志,对比两次点击的frontImg/backImg内容:
$(".button").click(function(){ console.log("当前frontImg:", frontImg); // 打印变量内容 console.log("当前backImg:", backImg); var doc = new jsPDF('landscape'); // ... 剩余代码不变 });
如果两次输出的dataURI完全一致,说明修改选项时的变量更新逻辑存在问题,需要检查对应代码是否正确执行(比如事件绑定错误、变量作用域问题等)。
第二步:解决浏览器缓存问题
如果变量确实已更新,需破解浏览器对dataURI的缓存:
方法1:给dataURI添加唯一标识
在dataURI末尾追加一个随时间变化的哈希值,让浏览器认为是新资源:
$(".button").click(function(){ var doc = new jsPDF('landscape'); // 添加唯一缓存破折号 doc.addImage(frontImg + `#${Date.now()}`, 'PNG', 0, 0, 300, 210); doc.addPage('a6','l'); doc.addImage(backImg + `#${Date.now()}`, 'PNG', 0, 0, 300, 210); doc.save('file.pdf'); });
方法2:将dataURI转为Blob对象生成临时URL
通过Blob对象创建唯一的临时URL,彻底避免缓存:
// 工具函数:将dataURI转为Blob function dataURItoBlob(dataURI) { const byteString = atob(dataURI.split(',')[1]); const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; const ab = new ArrayBuffer(byteString.length); const ia = new Uint8Array(ab); for (let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ab], { type: mimeString }); } $(".button").click(function(){ // 转换为Blob并生成临时URL const frontBlob = dataURItoBlob(frontImg); const backBlob = dataURItoBlob(backImg); const frontUrl = URL.createObjectURL(frontBlob); const backUrl = URL.createObjectURL(backBlob); var doc = new jsPDF('landscape'); doc.addImage(frontUrl, 'PNG', 0, 0, 300, 210); doc.addPage('a6','l'); doc.addImage(backUrl, 'PNG', 0, 0, 300, 210); doc.save('file.pdf'); // 释放临时URL,避免内存泄漏 URL.revokeObjectURL(frontUrl); URL.revokeObjectURL(backUrl); });
内容的提问来源于stack exchange,提问作者Michael Mayorga
相关产品推荐
相关产品推荐

