Puppeteer screenshot has missing/invisible text

眉间皱痕 提交于 2019-12-13 02:50:22

问题


I'm using puppeteer to save and download images from markup & css sent to an express app by the browser. Express compiles the template, just inserting the POSTed markup into an html shell & gets the css locally (mounted on a docker volume).

When I render the html & css directly in chrome, all text and other elements display as expected. The screenshot that is saved, however, is missing the text.

When I leave out our styles, the text renders the same way in both local chrome & the image saved by puppeteer.

Are there styles set behind the scenes? Something else that could account for the difference?

EDIT: It now seems that it might be related to a race condition unhandled somewhere in my code. Without making changes, I was able to get the expected image, but only sometimes and I haven't yet been able to sort out what's different about those times.

Steps to reproduce

  • Puppeteer version: 0.12.0
  • Platform / OS version: docker/ubuntu
  • Node.js version: 8

index.js:

app.post('/img', function (req, res) {
  const puppeteer = require('puppeteer');
  let css = [];
  let stylesheets = [];
  // 
  // separate out local stylesheets and read contents of the files
  // 
  css = req.body.stylesheets.filter(sheet => {
    return sheet.indexOf('https') === -1 && sheet.indexOf('http') === -1;
  });
  css = css.map(sheet => {
    return fs.readFileSync(path.join(__dirname, sheet));
  });
  // 
  // separate out external stylesheets (bootstrap, etc)
  // 
  stylesheets = req.body.stylesheets.filter(sheet => {
    return sheet.indexOf('https') > -1 || sheet.indexOf('http') > -1;
  });
  //
  // compile template with html & styles
  //
  app.render('img', {
    stylesheets: stylesheets,
    content: req.body.content,
    css: css
  }, function (err, html) {
    console.log('html\n', html);
    (async() => {
      const browser = await puppeteer.launch({args: ['--no-sandbox']});
      const page = await browser.newPage();
      await page.setViewport({width: 1300, height: 1200});
      //
      // load html to chrome
      //
      try {
        const loaded = page.waitForNavigation({
          waitUntil: 'load'
        });
        await page.setContent(html);
        await loaded
      } catch(err) {
        console.log(err);
        res.status(err.status).send('There was an error loading the page.');
      }
      //
      // save image
      //
      const filename = `${req.body.title}.png`;
      const filepath = path.join(__dirname, 'img', filename);
      try {
        await page.screenshot({ path: filepath });
        console.log(`${filename} saved`);
      } catch(err) {
        console.log(err);
        res.status(err.status).send('There was a problem saving the image.');
      }
      res.status(201).send(filename);
    })();
  });
});

img.html (template):

<!DOCTYPE html>
<html>
<head>
  <title>{{title}}</title>
  {{#stylesheets}}
  <link rel="stylesheet" type="text/css" href="{{{.}}}">
  {{/stylesheets}}
  {{#css}}
  <style type="text/css">
    {{{.}}}
  </style>
  {{/css}}
</head>
<body>
  {{{content}}}
</body>
</html>

Expected

Without local styles:

With local styles:

Actual

Without local styles is as expected.

With local styles:


回答1:


It's likely that your docker image doesn't have the necessary fonts. There's a lot of open-source images out there (I maintain one here: https://github.com/joelgriffith/browserless) that try and alleviate common problems like this.

This is mostly its due to the base image not having the appropriate fonts.



来源:https://stackoverflow.com/questions/48324728/puppeteer-screenshot-has-missing-invisible-text

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!