2016-12-19 82 views
0

一位朋友要求我捕獲使用React.js構建的客戶端渲染網站,最好使用PhantomJS。我用一個簡單的渲染腳本如下:使用PhantomJS渲染React.js clientside webapp

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(); 
}); 

的URL爲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承諾本身不由PhantomJS支持,所以我嘗試了各種額外的軟件包,如下面的https://www.npmjs.com/package/es6-promise,併發起了這樣的變量:

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

但是這仍然會產生相同的錯誤,儘管Promise現在是一個函數。網頁的輸出仍然是空的(顯然..)

現在我很老派,所以這整個客戶端渲染的東西是有點超越我(在每個方面),但也許有人有一個解決方案。我已經嘗試過使用一個等待腳本,但是那絕對沒有。我是否完全錯誤?這甚至有可能做到嗎?

非常感謝!

Ludwig

+0

PhantomJS有其自己可怕的Javascript實現,而不是像Node一樣使用某種理智的東西。如果你想與其他Node庫一起使用Phantom,你必須使用可怕的集成軟件,如https://github.com/amir20/phantomjs-node –

+0

@AndyRay有一點。你應該使用類似[Nightmare](https://github.com/segmentio/nightmare)的Node。 –

+0

好酷的傢伙,會檢查出來!謝謝 –

回答

0

我已經嘗試了你鏈接的polyfill,它沒有工作,更改爲core.js,並能夠做出截圖。您需要在打開頁面之前注入填充:

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); 

}); 
+0

好吧,聽起來很有希望。謝謝! 但是我已經安裝了core.js使用'npm我core-js'然後(請原諒我的不高興在這裏)我怎麼實際訪問它? –

+0

指出計算機上core.js文件的路徑:'page.injectJs('local/path/to/file/core.js')'。最簡單的方法是將其移動到PhantomJS腳本所在的目錄。 – Vaviloff

+0

曾經忽略了core-js包的'/ client /'目錄,已經很累了。無論如何,這似乎工作!非常感謝。 –

0

您需要了解的是,有幾個頁面加載部分。首先是HTML - 與您在網頁上「查看源代碼」時看到的內容相同。接下來是加載的圖像和腳本以及其他資源。然後執行這些腳本,這可能會導致更多的內容被加載並且可能修改HTML。

你必須做的是找出一種方法來確定何時頁面實際上是「加載」,因爲用戶看到它。 PhantomJS爲您提供了一個範例來加載waitFor內容。仔細閱讀他們的例子,看看你能否找出適合你的方法。請特別注意他們將phantom.exit();放在哪裏,因爲您想確保在最後發生。祝你好運。

+0

雖然在許多情況下都是如此,但使用React應用程序還有許多其他問題。對我而言,它並沒有在我的webpack配置文件中包含'es2015',因此它沒有正確地將類編譯爲適合瀏覽器的代碼。 –

0

你想在哪裏初始化Promise?您需要將其創建爲window的屬性,或使用es6-promise作爲全局填充,如require('es6-promise').polyfill();require('es6-promise/auto');(來自readme)。

另外,你是什麼意思的「捕獲」?如何如果你想抓取數據,使用X-ray可能會有更好的運氣。它支持幻影,噩夢和其他驅動程序。

請記住React也可以被渲染。 React就像模板,但帶有實時數據綁定。這並不像你想要的那麼複雜。

+0

感謝您的回答。我實際上嘗試過'require('es6-promise')。polyfill();'並將Promise設置爲'window'的屬性,但都沒有成功。 是的我的意思是刮數據,謝謝你的建議,我會檢查一下。 我意識到這一點,但這是超出我的控制:) –