使用PhantomJS渲染React.js客户端webapp

时间:2016-12-19 19:09:31

标签: javascript reactjs promise phantomjs serverside-rendering

一位朋友要我捕获一个使用React.js构建的客户端渲染网站,最好使用PhantomJS。我使用如下的简单渲染脚本:

var system = require('system'),
fs = require('fs'),
page = new WebPage(),
url = system.args[1],
output = system.args[2],
result;

page.open(url, function (status) {
if (status !== 'success') {
  console.log('FAILED to load the url');
  phantom.exit();
} else {
  result = page.evaluate(function(){
      var html, doc;

      html = document.querySelector('html');

      return html.outerHTML;
  });

  if(output){

    var rendered = fs.open(output,'w');
    rendered.write(result);
    rendered.flush();
    rendered.close();

  }else{

    console.log(result);

  }
}
phantom.exit();
});

网址为http://azertyjobs.tk

我一直都会收到错误

ReferenceError: Can't find variable: Promise

http://azertyjobs.tk/build/bundle.js:34
http://azertyjobs.tk/build/bundle.js:1 in t
...

好的,所以我发现ES6 Promise还没有被PhantomJS原生支持,所以我尝试了各种额外的软件包,如下面的https://www.npmjs.com/package/es6-promise并启动变量:

var Promise = require('es6-promise').Promise

然而,尽管Promise现在是一个函数,但它仍会产生相同的错误。网页的输出仍然是空的(显然是......)

现在我已经很老了,所以整个客户端渲染的东西都超出了我(在每个方面),但也许有人有解决方案。我也试过使用等待的脚本,但这并没有带来什么。我完全错了吗?这甚至可以吗?

非常感谢!

路德维希

3 个答案:

答案 0 :(得分:0)

您需要了解的是页面加载的几个部分。首先是HTML - 您在网页上“查看源代码”时看到的内容相同。接下来是加载的图像和脚本以及其他资源。然后执行脚本,这可能会也可能不会导致更多内容被加载以及可能对HTML进行修改。

你必须做的就是找出一种方法来确定当用户看到页面实际上“加载”的时间。 PhantomJS为您提供加载waitFor内容的范例。仔细阅读他们的例子,看看你是否能找到适合你的方法。请特别注意他们放置phantom.exit();的位置,以确保最后发生。祝你好运。

答案 1 :(得分:0)

您在哪里(如何)初始化Promise?您需要将其创建为window的属性,或将es6-promise用作全局polyfill,例如require('es6-promise').polyfill();或此require('es6-promise/auto');(来自readme) 。

另外,“捕获”是什么意思?如果您正在尝试抓取数据,使用X-ray可能会有更好的运气。它支持Phantom,Nightmare和其他驱动程序。

请记住,React也可以是服务器呈现的。 React就像模板,但有实时数据绑定。它并不像你想要的那么复杂。

答案 2 :(得分:0)

我已经尝试过您关联的polyfill,但它无法正常工作,已更改为core.js并且能够制作屏幕截图。您需要在打开页面之前注入polyfill:

page.onInitialized = function() {
    if(page.injectJs('core.js')){
        console.log("Polyfill loaded");
    }    
}

page.open(url, function (status) {

    setTimeout(function(){
        page.render('output.jpg');
        phantom.exit();
    }, 3000);

});