我需要呈現HTML頁面服務器端並「提取」canvas元素的原始字節,以便將其保存爲PNG。問題是,canvas元素是從JavaScript創建的(我使用jQuery的Flot生成圖表,基本上)。所以我想我需要一種方法來從瀏覽器「託管」DOM + Javascript功能,而無需使用瀏覽器。我解決了mshtml(但對任何和所有的建議開放),因爲它似乎應該能夠到這一點。這是一個ASP.NET MVC項目。渲染HTML + Javascript服務器端
我已經搜索了很多,並沒有看到任何結論。
所以我有這個簡單的HTML - 例如保持儘可能簡單說明問題 -
<!DOCTYPE html>
<html>
<head>
<title>Wow</title>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js" type="text/javascript"></script>
</head>
<body>
<div id="hello">
</div>
<script type="text/javascript">
function simple()
{
$("#hello").append("<p>Hello</p>");
}
</script>
</body>
</html>
從瀏覽器中運行時產生預期的輸出。
我希望能夠將原始HTML加載到內存中,執行JavaScript函數,然後操作最終的DOM樹。我不能使用任何System.Windows.WebBrowser類,因爲我的代碼需要在服務環境中運行。
因此,這裏是我的代碼:
IHTMLDocument2 domRoot = (IHTMLDocument2)new HTMLDocument();
using (WebClient wc = new WebClient())
{
using (var stream = new StreamReader(wc.OpenRead((string)url)))
{
string html = stream.ReadToEnd();
domRoot.write(html);
domRoot.close();
}
}
while (domRoot.readyState != "complete")
Thread.Sleep(SleepTime);
string beforeScript = domRoot.body.outerHTML;
IHTMLWindow2 parentWin = domRoot.parentWindow;
parentWin.execScript("simple");
while (domRoot.readyState != "complete")
Thread.Sleep(SleepTime);
string afterScript = domRoot.body.outerHTML;
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domRoot);
domRoot = null;
的問題是, 「beforeScript」 和 「afterScript」 是完全一樣的。 IHTMLDocument2實例通過正常的「未初始化」,「加載」,「完成」循環,沒有錯誤拋出,沒有。
任何人有什麼想法我做錯了什麼?完全迷失在這裏。
感謝您抽空回覆的時間,但我會和你說什麼不同意 - 關於「不打算」。瀏覽器的可視區域(窗口)應該與其內部的DOM/Javascript引擎分開。爲什麼它應該將結果呈現在哪裏?爲什麼不能在內存中的任何位置渲染DOM + CSS + Javascript?事實上,有一個Node.js與Flot進行交互的例子來完成我想要做的事情 - 生成圖表服務器端。可悲的是,我不能使用Node.js ... –
關於我需要在服務器上執行的操作 - 我需要定期在無頭,非交互式環境中生成圖表(現在使用Flot)。圖表必須與用戶在瀏覽器中查看網頁時完全一樣。這是一個ASP.NET MVC項目,我還沒有找到任何服務器端控件/組件來輕鬆完成此操作。 –
是的,基本上你是對的。將DOM + CSS + Javascript渲染到內存中真的很有意義。但是,我希望這可以與瀏覽器一起使用,而瀏覽器無法在非交互式會話中加載。無論如何,我祝你好運,如果你繼續這樣做。 –