Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无法从jsPDF fromHTML进行AJAX调用_Javascript_Ajax_Jspdf - Fatal编程技术网

Javascript 无法从jsPDF fromHTML进行AJAX调用

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 = {

我有一个简单的结构,它从jsPDF生成PDF,获取“datauristring”,并将其传递到AJAX请求中。但是,AJAX方法不会启动。当它尝试“发送”时,抛出异常“h未定义”。我通过跟踪XHR请求和jQuery库中出现的内容来了解这一点。我能不能在jsPDF回调后这么快启动AJAX请求

我应该注意,我正在将PDF发送到一个服务,该服务将该PDF与另一个PDF合并,并返回一个全新的文档

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数据没有填充。对不起,这不是一个好的解释。有趣的是,关于原始二进制数据,我没有尝试过。非常感谢。