Node.js 呈现页面时,可以';不要加载外部资源

Node.js 呈现页面时,可以';不要加载外部资源,node.js,pdf-generation,phantomjs,Node.js,Pdf Generation,Phantomjs,我目前正试图通过Node&PhantomJS从HTML页面生成一个PDF文档 如果我的页面包含本地资源,或仅包含静态内容,则可以正常工作: <!doctype html> <html> <head> <meta charset="UTF-8" /> <link rel="StyleSheet" media="screen" href="./style.css" /> <lin

我目前正试图通过Node&PhantomJS从HTML页面生成一个PDF文档

如果我的页面包含本地资源,或仅包含静态内容,则可以正常工作:

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8" />
        <link rel="StyleSheet" media="screen" href="./style.css" />
        <link rel="StyleSheet" media="print" href="./print.css" />
    </head>
    <body>
        <h1>The title</h1>
        <p>hai <span class="foo">lol <span class="bar">I'm generating</span> a pdf</span> !</p>
        <p class="centre"><img src="http://www.gratuit-en-ligne.com/telecharger-gratuit-en-ligne/telecharger-image-wallpaper-gratuit/image-wallpaper-animaux/img/images/image-wallpaper-animaux-autruche.jpg" /></p>
        <canvas id="test_canvas" width="200px" height="100px"/>

        <script>
            setTimeout(function () {
                var ctx = document.getElementById('test_canvas').getContext('2d');

                ctx.fillStyle = '#FF0000';
                ctx.fillRect(0, 0, 150, 75);
            }, 1000);

            setTimeout(function () {
                evt = document.createEvent('CustomEvent');
                evt.initEvent('pdfTrigger', true, false);

                document.dispatchEvent(evt);
            }, 3000);
        </script>
    </body>
</html>
图像未渲染;如果我尝试使用来自cdn的jQuery include和一些jQuery代码(比如通过
$(document).trigger('pdfTrigger')
)触发事件),它会说
ReferenceError:找不到变量:$
,因此事件永远不会触发。如果我将其包含在本地资源的html文件中(如
),错误将消失,但事件将永远不会触发

下面是我正在使用的phantomjs脚本:

/**
 * Render a PDF from an HTML file
 *
 * @author Baptiste Clavié <baptiste@wisembly.com>
 * Adapted from PhantomJs' example "rasterize.js"
 */

var orientation = 'portrait',
    system = require('system'),
    args = system.args.slice(1);

if (args.length < 2 || args.length > 3) {
    system.stderr.writeLine('Usage: rasterize.js source output [orientation]');
    system.stderr.writeLine('   source : html source to put in the pdf');
    system.stderr.writeLine('   output : output when the pdf will be written');
    system.stderr.writeLine('   orientation : document orientation (either portrait or landscape');

    phantom.exit((args.length === 1 & args[0] === '--help') ? 0 : 1);
}

if (typeof args[2] !== 'undefined') {
    if (-1 === ['portrait', 'landscape'].indexOf(args[2])) {
        system.stderr.writeLine('Invalid argument for [orientation]');
        system.stderr.write('Expected either "portrait", either "landscape" ; got "' + args[2] + '"');

        phantom.exit(1);
    }

    orientation = args[2];
}

var page = require('webpage').create(),
    identifier = '___RENDER____';

page.paperSize = { format: 'A4', orientation: orientation, margin: '1cm' };

page.onInitialized = function() {
    page.evaluate(function(identifier) {
        document.addEventListener('pdfTrigger', function () {
            console.log(identifier);
        }, false);
    }, identifier);
};

page.onError = function (msg, trace) {
    system.stderr.writeLine(msg);

    trace.forEach(function(item) {
        system.stderr.writeLine('   ' + item.file + ':' + item.line);
    });

    phantom.exit(1);
}

page.onConsoleMessage = function (msg) {
    console.log(msg);

    if (msg !== identifier) {
        return;
    }

    page.render(args[1], { format: 'pdf' });
    phantom.exit(0);
}

page.open(args[0], function (status) {
    if (status !== 'success') {
        system.stderr.write('Unable to load the file "' + args[0] + '"');
        phantom.exit(1);
    }
});
/**
*从HTML文件呈现PDF
*
*@作者巴蒂斯特·克拉维
*改编自PhantomJs的示例“rasterize.js”
*/
变量方向='纵向',
系统=要求(“系统”),
args=system.args.slice(1);
如果(args.length<2 | | args.length>3){
system.stderr.writeLine('用法:rasterize.js源输出[orientation]”);
system.stderr.writeLine('source:html source放入pdf');
system.stderr.writeLine('output:pdf写入时的输出');
system.stderr.writeLine('方向:文档方向(纵向或横向));
phantom.exit((args.length==1&args[0]==='--help')?0:1);
}
如果(参数类型[2]!=='undefined'){
if(-1===['strital','scape'].indexOf(args[2])){
system.stderr.writeLine([orientation]的参数无效);
system.stderr.write('应为“纵向”或“横向”;应为“'+args[2]+'”);
幻影。出口(1);
}
方向=args[2];
}
var page=require('webpage')。create(),
标识符='______;';
page.paperSize={格式:'A4',方向:方向,边距:'1cm'};
page.onInitialized=函数(){
第页评估(功能(标识符){
document.addEventListener('pdfTrigger',函数(){
console.log(标识符);
},假);
},标识符);
};
page.onError=函数(消息,跟踪){
系统标准写入线(msg);
trace.forEach(函数(项){
system.stderr.writeLine(''+item.file+':'+item.line);
});
幻影。出口(1);
}
page.onConsolleMessage=函数(msg){
控制台日志(msg);
如果(消息!==标识符){
返回;
}
render(args[1],{format:'pdf'});
幻影出口(0);
}
第页打开(参数[0],函数(状态){
如果(状态!=“成功”){
system.stderr.write('无法加载文件“'+args[0]+'”);
幻影。出口(1);
}
});
要启动脚本,我使用以下命令:
phantomjs rasterize.pdf test.html test.pdf

总而言之,当我试图在Phantom中呈现html时,似乎无法从html加载任何外部内容,并且无法识别jQuery(可能还有其他脚本?)

有什么想法吗?如果需要更高的精度,请不要犹豫。

更改:

setTimeout(function () {
    evt = document.createEvent('CustomEvent');
    evt.initEvent('pdfTrigger', true, false);

    document.dispatchEvent(evt);
}, 3000);
致:


失败的原因是该图像非常大,并且您在正确下载图像之前触发了pdf事件。使用
window.onload
是可靠的,因为
onload
事件只会在加载所有页面资源后运行。

这可以实现加载外部资源的功能,但是现在我遇到了另一个与此无关的问题。请注意,
setTimeout
在这里的用法只是为了模拟“在我的网页上做事”,因为您可以想象给定的html并不是我真正想要呈现的。谢谢。:)然后只需执行
window.onload=function(){setTimeout(function()){/*做一些事情,然后发送pdf事件*/},3000);};
是的,这就是我想继续下一个问题的原因。:)
setTimeout(function () {
    evt = document.createEvent('CustomEvent');
    evt.initEvent('pdfTrigger', true, false);

    document.dispatchEvent(evt);
}, 3000);
window.onload = function () {
    evt = document.createEvent('CustomEvent');
    evt.initEvent('pdfTrigger', true, false);

    document.dispatchEvent(evt);
};