2011-12-05 179 views
6

我需要呈現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實例通過正常的「未初始化」,「加載」,「完成」循環,沒有錯誤拋出,沒有。

任何人有什麼想法我做錯了什麼?完全迷失在這裏。

回答

1

我發現Awesomium是否正是我需要什麼! 「無窗口的Web瀏覽器框架」。輝煌。

1

基本上你正在嘗試做的事情,而不是打算這樣做。

您將生成HTML + Javascript以便瀏覽器進行繪製。您編寫C#以啓用任何類型的服務器端事物。

在服務器上生成HTML + Javascript以將其加載到瀏覽器上的服務器能夠保存PNG聲音不好。

您是否想過使用服務器端C#組件生成圖像等其他方法? 基本上,你爲什麼真的需要將它保存在服務器上?也許有人可以提供更好的解決方案?

+0

感謝您抽空回覆的時間,但我會和你說什麼不同意 - 關於「不打算」。瀏覽器的可視區域(窗口)應該與其內部的DOM/Javascript引擎分開。爲什麼它應該將結果呈現在哪裏?爲什麼不能在內存中的任何位置渲染DOM + CSS + Javascript?事實上,有一個Node.js與Flot進行交互的例子來完成我想要做的事情 - 生成圖表服務器端。可悲的是,我不能使用Node.js ... –

+0

關於我需要在服務器上執行的操作 - 我需要定期在無頭,非交互式環境中生成圖表(現在使用Flot)。圖表必須與用戶在瀏覽器中查看網頁時完全一樣。這是一個ASP.NET MVC項目,我還沒有找到任何服務器端控件/組件來輕鬆完成此操作。 –

+0

是的,基本上你是對的。將DOM + CSS + Javascript渲染到內存中真的很有意義。但是,我希望這可以與瀏覽器一起使用,而瀏覽器無法在非交互式會話中加載。無論如何,我祝你好運,如果你繼續這樣做。 –