2011-12-05 137 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渲染到内存中真的很有意义。但是,我希望这可以与浏览器一起使用,而浏览器无法在非交互式会话中加载。无论如何,我祝你好运,如果你继续这样做。 –