问题
I'm making a route in my webapp that turns some html into a pdf. This works great in development, but fails on Heroku. Other Puppeteer tasks work fine on heroku. The HTML I'm rendering is quite small.
const generatePDF = asyncMiddleware(async (req, res) => {
const browser = await puppeteer.launch({
dumpio: true,
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
page.on('error', err => {
console.error('err', err, err.stack)
browser.close();
});
await page.goto(`data:text/html,${req.body.html}`, {
waitUntil: 'networkidle2',
});
// stupid attempt at debugging, making sure page has time to render?
await page.waitFor(6000);
const pdf = await page.pdf();
res.set('content-type', 'application/pdf');
await browser.close();
res.send(pdf);
});
module.exports = require('express')
.Router()
.post('/', generatePDF)
When I hit the route on Heroku, I get a blank PDF. Puppeteer produces the following stdout
[0131/123556.374089:ERROR:gpu_process_transport_factory.cc(1043)] Lost UI shared context.
When I wrote this code I was on version 0.10.x, but I thought upgrading might help, so I went up at 1.0.0. The problem persists on both versions. Node version is 8.x.x
I thought it might be a server memory issue, so I upgraded to a 2x dyno, but that didn't help.
I think it could be related to one of these two issues: - https://github.com/GoogleChrome/puppeteer/issues/1875 - https://github.com/GoogleChrome/puppeteer/issues/1925
But, these don't seem super related to Heroku, or explain how it works in one env and not another
Update: when I look at the payload, the data of the pdf looks like a UUID!
回答1:
I figured it out! The client to my server was axios. I needed to tell axios that I was serving up binary.
const { data: pdf } = await req({
method: 'post',
url: 'api/pdfs',
responseType: 'arraybuffer', // <-- this was missing
data: { html }
});
来源:https://stackoverflow.com/questions/48542991/puppeteer-pdf-blank-on-heroku