问题
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