Search code examples
node.jsstrapipdfkit

Error in sending pdfkit doc from node.js to client


I am trying to send a pdf file generated using pdfkit in node.js to the client.

If my pdf contains any image, then my code will give the following error. Otherwise (without any image), this code will work without errors

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

This is my code

var doc = new PDFDocument({
              bufferPages: true,
            }),
    svg = mySvg;

SVGtoPDF(doc, svg, 0, 0);
let buffers = [];

doc.on("data", buffers.push.bind(buffers));
doc.on("end", () => {
    let pdfData = Buffer.concat(buffers);
    ctx.res
    .writeHead(200, {
        "Content-Length": Buffer.byteLength(pdfData),
        "Content-Type": "application/pdf",
        "Content-disposition": "attachment;filename=file.pdf",
    })
    .end(pdfData);
});
doc.end();

I am using strapi as my backend framework. When I tried to write the file to the server, then it will work fine. But I need to send the file without storing in the server.


Solution

  • I think the problem in doc.pipe(ctx.res). Try to add after .end(pdfData)

    res.writeHead(200, {
      'Content-Type': 'application/pdf',
      'Access-Control-Allow-Origin': '*',
      'Content-Disposition': `attachment; filename=${fileName}`,
    });
    
    doc.pipe(ctx.res);
    doc.end();
    
    

    For me it works fine, but after 3-4 downloads response is a timed out. Moved doc.on("data", buffers.push.bind(buffers)); at the start doc

    let buffers = [];
    doc.on('data', buffers.push.bind(buffers));
    
    /* doc body here */
    doc.text('pdf');
    doc.text('pdf2');
    doc.text('pdf3');
    
    doc.on('end', () => {
        const pdfData = Buffer.concat(buffers);
        res.writeHead(200, {
          'Content-Length': Buffer.byteLength(pdfData),
          'Content-Type': 'application/pdf',
          'Content-disposition': `attachment; filename=${filename}.pdf`,
          'Access-Control-Allow-Origin': '*',
        }).end(pdfData);
      });
    
    doc.end();