marcbachmann / node-html-pdf

This repo isn't maintained anymore as phantomjs got dreprecated a long time ago. Please migrate to headless chrome/puppeteer.
MIT License
3.56k stars 545 forks source link

Img hosted by an SSL site using Let's Encrypt (ACME v2) does not load in PDF #652

Open jacbar01 opened 2 years ago

jacbar01 commented 2 years ago

We have a node.js application that has been using node-html-pdf from the beginning with no issue. The PDF's generated include pictures hosted on the application site, using SSL (https://mysite/mypicture). We are using Let's encrypt as our certificate authority.

Recently we upgraded to the newest certificate model of Let's encrypt (ACME v2). As a side effect the images would no longer load when we generate the PDF's. We have confirmed this to be the issue by successfully replacing the regular images with fake images hosted by http servers, or with https servers that are still using an older type of certificate.

Is there any solution for node-html-pdf to be compatible with our new certificate?

FransGH commented 2 years ago

Stumbled over the same problem. Seems to be caused by PhantomJS:

https://newbedev.com/phantomjs-failing-to-open-https-site

Specifically it doesn't seem to support the new Let's Encrypt Root Certificate.

I might try to patch html-pdf to tell phantomjs to ignore ssl altogether but still researching if there is a better solution.

marcbachmann commented 2 years ago

Please update the root certificates on your system. Image loading is working against for me against http servers using letsencrypt certificates.

jacbar01 commented 2 years ago

Please update the root certificates on your system. Image loading is working against for me against http servers using letsencrypt certificates.

We have updated the root certificates. It is actually when we updated them - not just renewed them but specifically updated them to the new format - that the issue arose.

abea commented 2 years ago

We also ran into this. Passing the --ignore-ssl-errors=yes argument in phantomArgs resolved it. Obviously seems less than ideal, but works for now.

samlogan commented 2 years ago

Any updates on this? I tried adding --ignore-ssl-errors=yes as per the below:

{
  format: 'A4',
  orientation: 'portrait',
  type: 'pdf',
  zoomFactor: '1',
  phantomArgs: ['--ignore-ssl-errors=yes']
}

But no luck :( All images are 404'ing

ybrodsky commented 2 years ago

This is still broken. The phantomArgs does not work.

raysubham commented 2 years ago

Same here, no luck with phantomArgs

marco910 commented 2 years ago

I had the same problem and for me, it worked to add phantomArgs: ['--ignore-ssl-errors=yes'] to the options object for html-pdf.

Razzwan commented 2 years ago

This solution works fine for me:

import * as htmlToPdf from 'html-pdf';

const options: htmlToPdf.CreateOptions = {
  format: 'Letter',
  // required to resolve image issues
  phantomArgs: ['--ignore-ssl-errors=yes'],
};

htmlToPdf.create('SOME HTML HERE', options).toFile(`file-name`, (err, fileInfo) => {
  if (err) {
    reject(err);
    return;
  }

  console.log('pdf file generated successfully');
});

Perhaps toFile works, but toStream and/or toBuffer doesn't?

marco910 commented 2 years ago

@Razzwan I'm using this code and toBuffer is working very well

const pdf_options = {
    format: "Letter",
    orientation: "portrait",
    localUrlAccess: true,
    border: 0,
    phantomArgs: ["--ignore-ssl-errors=yes"],
  };

pdf.create(template, pdf_options).toBuffer(function (err, buffer) {
    if (err) {
      // On error
      console.log(err);
      return res.status(500).json({ message: "Error", error: err });
    } else {
      // On success
      const base64 = buffer.toString("base64");
      fs.writeFileSync(`${output_path}/${filename}`, buffer);
      return res.status(200).json({
        buffer: base64,
      });
    }
  });
hawale commented 10 months ago

This solution works fine for me:

import * as htmlToPdf from 'html-pdf';

const options: htmlToPdf.CreateOptions = {
  format: 'Letter',
  // required to resolve image issues
  phantomArgs: ['--ignore-ssl-errors=yes'],
};

htmlToPdf.create('SOME HTML HERE', options).toFile(`file-name`, (err, fileInfo) => {
  if (err) {
    reject(err);
    return;
  }

  console.log('pdf file generated successfully');
});

Perhaps toFile works, but toStream and/or toBuffer doesn't?

worked for me

function createPdfForCatalogueName(pdfTemplate, priorityOptions, configItem, callback, res) { priorityOptions = (priorityOptions) ? priorityOptions : {}; let options = { height: "11.69in", width: "8.26in", // header: { // height: "20mm" // }, // footer: { // height: "10mm", // }, phantomArgs: ['--ignore-ssl-errors=yes'], }; options = Object.assign(priorityOptions, options); let filename = craeteFilenameForCatalogue(configItem.keyToUse || 'doc_key'), pathToSave = configItem.pathToSave || 'public/uploads/default/'; pathToSave = path.join(global.__base, pathToSave + filename); pdf.create(pdfTemplate, options).toFile(pathToSave, function (err, data) { // console.log('err, data : ', err, data); if (err) { // res.send(err); callback(err); } else { // res.send("File created successfully"); callback(null, { filename: filename, path: pathToSave }); } }); }