Javascript 无法从jsPDF fromHTML进行AJAX调用
我有一个简单的结构,它从jsPDF生成PDF,获取“datauristring”,并将其传递到AJAX请求中。但是,AJAX方法不会启动。当它尝试“发送”时,抛出异常“h未定义”。我通过跟踪XHR请求和jQuery库中出现的内容来了解这一点。我能不能在jsPDF回调后这么快启动AJAX请求 我应该注意,我正在将PDF发送到一个服务,该服务将该PDF与另一个PDF合并,并返回一个全新的文档Javascript 无法从jsPDF fromHTML进行AJAX调用,javascript,ajax,jspdf,Javascript,Ajax,Jspdf,我有一个简单的结构,它从jsPDF生成PDF,获取“datauristring”,并将其传递到AJAX请求中。但是,AJAX方法不会启动。当它尝试“发送”时,抛出异常“h未定义”。我通过跟踪XHR请求和jQuery库中出现的内容来了解这一点。我能不能在jsPDF回调后这么快启动AJAX请求 我应该注意,我正在将PDF发送到一个服务,该服务将该PDF与另一个PDF合并,并返回一个全新的文档 var docX = new jsPDF("p", "pt", "letter"); margins = {
var docX = new jsPDF("p", "pt", "letter");
margins = {
top: 20,
bottom: 20,
left: 20,
width: 522
};
specialElementHandlers = {
// element with id of "bypass" - jQuery style selector
'#bypassme': function (element, renderer) {
// true = "handled elsewhere, bypass text extraction"
return true
}
};
docX.fromHTML (
document.getElementById('productModalContent'),
margins.left,
margins.top, {
'width' : margins.width,
'elementHandlers': specialElementHandlers
},
function (dispose) {
specDoc = (docX.output('datauristring'));
console.log(dispose);
//docX.save('asdfas.pdf');
//console.log(specDoc);
processPDF(specDoc);
}, margins
);
function processPDF(doc) {
console.log(doc.length);
$.ajax({
type: "POST",
url: "https://someurl",
data: {
'partNumber' : '$!{rawPartNumber}',
'region' : '$!{regionContentlet.code}',
'doc' : doc
},
cache: false,
success: function(data) {
console.log("success?");
var link=document.createElement('a');
link.href='data:application/pdf;base64,' + data;
link.download="myfile.pdf";
link.setAttribute('target', '_blank');
link.click();
},
error: function(data) {
console.log(data);
}
});
}
编辑:删除ajax并添加fetch
const response = await fetch('myurl', {
method: 'POST',
body: {
'partNumber' : '$!{rawPartNumber}',
'region' : '$!{regionContentlet.code}',
'myDiv' : doc
}
});
对于任何可能会停下来问这个问题的人,我确实解决了我的问题。我无法在jsPDF的fromHTML函数中使用AJAX调用。我最终得到了第一个PDF作为base64字符串,然后调用jsPDF的fromHTML来获取第二个PDF数据集,最后使用PDF库将两个PDF全部用js缝合在一起
<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
<script src="https://unpkg.com/pdf-lib/dist/pdf-lib.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script>
async function processPDF() {
$.ajax({
type: "POST",
url: 'mypdfurl',
data: {
},
cache: false,
success: function(data) {
console.log("success?");
var docX = new jsPDF("p", "pt", "letter");
margins = {
top: 20,
bottom: 20,
left: 20,
width: 575,
};
specialElementHandlers = {
// element with id of "bypass" - jQuery style selector
'#bypassme': function (element, renderer) {
// true = "handled elsewhere, bypass text extraction"
return true
},
'.info': function (element, renderer) {
element.style.fontSize = "12px";
},
'.spec': function (element, renderer) {
element.style.fontSize = "12px";
},
'.attribute': function (element, renderer) {
element.style.fontSize = "12px";
},
'#logoProductPrint': function(element, renderer) {
var ele = element.firstElementChild;
ele.setAttribute("style", "width:80px;height:50px");
},
};
var itm = document.getElementById('productPrint');
var itm_p = itm.cloneNode(true);
synchronizeCssStyles(itm, itm_p, true);
docX.fromHTML (
//document.getElementById('productPrint'),
itm_p,
margins.left,
margins.top,
{
'width' : margins.width,
'elementHandlers': specialElementHandlers,
},
async function (dispose) {
var specDoc = (docX.output('datauristring'));
const pdfDoc = await PDFLib.PDFDocument.create();
var d = 'data:application/pdf;base64,' + data;
const firstDoc = await PDFLib.PDFDocument.load(d);
const secondDoc = await PDFLib.PDFDocument.load(specDoc);
const firstPage = await pdfDoc.copyPages(firstDoc, [0]);
pdfDoc.addPage(firstPage[0]);
const secondPage = await pdfDoc.copyPages(secondDoc, [0]);
pdfDoc.addPage(secondPage[0]);
const pdfBytes = await pdfDoc.save();
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const blobUrl = URL.createObjectURL(blob);
var link=document.createElement('a');
link.href=blobUrl;
link.setAttribute('target', '_blank');
link.click();
}, margins
);
},
error: function(data) {
console.log(data);
}
});
function synchronizeCssStyles(src, destination, recursively) {
// if recursively = true, then we assume the src dom structure and destination dom structure are identical (ie: cloneNode was used)
// window.getComputedStyle vs document.defaultView.getComputedStyle
// @TBD: also check for compatibility on IE/Edge
destination.style.cssText = document.defaultView.getComputedStyle(src, "").cssText;
if (recursively) {
var vSrcElements = src.getElementsByTagName("*");
var vDstElements = destination.getElementsByTagName("*");
for (var i = vSrcElements.length; i--;) {
var vSrcElement = vSrcElements[i];
var vDstElement = vDstElements[i];
// console.log(i + " >> " + vSrcElement + " :: " + vDstElement);
vDstElement.style.cssText = document.defaultView.getComputedStyle(vSrcElement, "").cssText;
}
}
}
}
不能使用第一种方法的原因是b/c必须将其作为blob获取,这样jQuery或xhr就不会尝试将二进制数据编码为文本。这样,您将获得损坏的数据。 您需要将其作为原始数据获取。jQuery在此b/c中不好,您不能将responsetype更改为blob。因此,您需要自己编写xhr请求,或者使用fetchAPI fetchurl.thenr=>r.blob.thencode
但是如果我第一眼看到的是,我可以从base64恢复到原始二进制以保存数据,并使用可能隐藏的方法使用正确的响应头下载pdf,那么我在jsPDF库中找到变量h的唯一位置就是rect和rect rounded函数中。这是有意义的,它是由呈现函数中的某个fromHTML调用的。但是,当我查看fromHTML的源代码时,它只接受4个参数,而不是6个。那么您使用的是哪个版本的jsPDF?因为如果您需要6个参数,那么我可能找错了lib,或者您的函数processPDF根本没有在unpkg.com中使用/jspdf@latest/dist/jspdf.min.js>是我正在使用的版本。不,我认为“h未定义”实际上在jquery libyou get console.logsuccess中?;或console.logdata;或者在那之前你有错误吗?您是否尝试过使用fetch请求而不是jquery来避免问题?这些都没有出现,这很奇怪。就好像jQuery并没有把它泡起来。我还没有试着去拿雪人,但它不能重现这个问题。我将您的代码复制到一个空html页面的标记中。我通过您提供的链接从google和jspdf加载了jquery 3.4.1。我看到ajax请求正在发出。一旦进入超时,我就会触发jquery错误处理程序。如果不使用jquery,您是否检查过服务器的响应是否正确?我们可能看到应用程序的错误部分。我也尝试了获取请求,但仍然无法正常工作。我确实得到了不同的行为,但我通过后端将PDF数据从jsPDF发送到的PDF数据没有填充。对不起,这不是一个好的解释。有趣的是,关于原始二进制数据,我没有尝试过。非常感谢。