PhantomJs: inline HTML with external CSS file

廉价感情. 提交于 2019-12-10 19:39:19

问题


I'm attempting to render some inline HTML which links to an external css file using the following PhantomJs script:

var page = require('webpage').create();
page.content = '';
page.content += '<html><head>';
page.content += '<link rel="stylesheet" href="http://example.com/css/layout.css" type="text/css" media="Screen">';
page.content += '</head><body>';
page.content += '<h1>test</h1>';
page.content += '</body></html>';

page.onResourceRequested = function(requestData, request) {
    console.log('::loading', requestData['url']);  // this doesn't get logged
};

page.onLoadFinished = function() {
    console.log('::rendering');
    page.render('output.png');
    phantom.exit();
};

The layout.css file can be accessed okay with wget

But here's the output of phantomjs:

$ ./phantomjs --debug=true render_demo.js
... snip ...
2014-01-06T12:17:53 [DEBUG] WebPage - updateLoadingProgress: 10
2014-01-06T12:17:53 [DEBUG] WebPage - updateLoadingProgress: 10
2014-01-06T12:17:53 [DEBUG] WebPage - updateLoadingProgress: 100
2014-01-06T12:17:53 [DEBUG] Network - Resource request error: 5 ( "Operation canceled" ) URL: "http://example.com/css/layout.css"
::rendering

There is no output .png file created.

Any ideas on how to ensure external CSS resources get fully loaded before rendering? It seems to work okay when I request the same html with page.open


回答1:


As benweet mentioned, you need to set page.content just once, as it will trigger a reload each time.

Because of that, in addition you will need to define your callbacks before actually setting the page content.

Try it like this instead:

var page = require('webpage').create();

page.onResourceRequested = function(requestData, request) {
  console.log('::loading', requestData['url']);  // this does get logged now
};

page.onLoadFinished = function() {
  console.log('::rendering');
  page.render('output.png');
  phantom.exit();
};

var content = '';
content += '<html><head>';
content += '<link rel="stylesheet" href="http://example.com/css/layout.css" type="text/css" media="screen">';
content += '</head><body>';
content += '<h1>test</h1>';
content += '</body></html>';
page.content = content;



回答2:


You have a setting named localToRemoteUrlAccessEnabled controlling if local pages can access remote ressources. It appears to default to false so you should try to change that.

PhantomJS settings are documented here, so changing this setting would be done like that in your code:

page.settings.localToRemoteUrlAccessEnabled = true;

just after the page creation. Since your page content is generated through scripting, I don't know if it is really considered local or remote. If this setting doesn't work, you could try setting webSecurityEnabled to false.




回答3:


You have to set page.content once. Calling the setter several times will load the page multiple times and cancel any previously unfinished async resource loading.

var page = require('webpage').create();
var content = '';
content += '<html><head>';
content += '<link rel="stylesheet" href="http://example.com/css/layout.css" type="text/css" media="Screen">';
content += '</head><body>';
content += '<h1>test</h1>';
content += '</body></html>';
page.content = content;


来源:https://stackoverflow.com/questions/20950013/phantomjs-inline-html-with-external-css-file

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