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