External CSS not taken into account on PhantomJS p

2019-09-07 17:16发布

问题:

I am running Phantom on a Node server, in order to generate pages from data and then render it as pdf.

However, while the pages work and are correctly rendered as pdf and everything, I cannot get them to take into account an external CSS file.

Here is a simplified version of what I am trying to do:

var phantom = require ('phantom');

phantom.create(function (ph) {
  ph.createPage(function (page) {
      var content = "";
      content += '<html><head>';
      content += '<link rel="stylesheet" href="/temp.css">'; 
      content += '<link rel="stylesheet" href="./temp.css">';
      content += '<link rel="stylesheet" href="temp.css">';
      content += '</head><body>';
      content += '<div class="myClass">I am supposed to be blue</div>';
      content += '</body></html>';
      page.set('content', content);

      setTimeout(function(){ 
          page.render("MyRenderedPDF.pdf", {format: 'pdf', quality: '100'}); 
      }, 1000)});
  }, {dnodeOpts: {weak: false}});

(I put the three CSS references to make SURE I didn't miss my CSS due to a basic relative path syntax issue)

And the CSS:

.myClass { color: blue; }

The PDF is rendered in the folder where my server is located. My CSS is located in the same folder.

Everything displays correctly in the PDF - but the text isn't blue.

I am aware I could just force a style value into the div, but the CSS we are using are pretty extensive, and I would rather find a way to access them directly.

Any idea on what I am missing?

回答1:

page.set('content', content); (or page.content = content in plain PhantomJS) is there to directly set the content of the page. When you do that, the domain the page is evaluated in is "about:blank". The resource "about:blank/temp.css" is simply not there.

I see two use cases here.

Resource is reachable from web

Either specify the full URL you want to load the resource from

content += '<link rel="stylesheet" href="http://example.com/path/temp.css">';
// OR
content += '<link rel="stylesheet" href="http://localhost/path/temp.css">';

or set the domain with page.setContent(html, url):

page.setContent(content, "http://localhost/path/", function(){
    page.render("MyRenderedPDF.pdf", {format: 'pdf', quality: '100'}, function(){
        ph.exit();
    }); 
});

Don't forget the callbacks, because the phantom module is different from plain PhantomJS scripts. See Functional Details for more information.

Resource is a local file without web server

You would have to use the fs module to read the file contents and put them as an embedded stylesheet.

content += '<style>' + fs.readFileSync("./temp.css") + '</style';