Рендеринг HTML+Javascript на стороне сервера

Мне нужно отобразить HTML-страницу на стороне сервера и «извлечь» необработанные байты элемента canvas, чтобы я мог сохранить его в PNG. Проблема в том, что элемент canvas создается из javascript (я использую Flot jquery для создания диаграммы, в основном). Поэтому я думаю, что мне нужен способ «разместить» функциональность DOM + Javascript из браузера без фактического использования браузера. Я остановился на mshtml (но открыт для любых предложений), так как кажется, что он должен быть в состоянии сделать именно это. Это ASP.NET MVC проект.

Я искал повсюду и не видел ничего убедительного.

Итак, у меня есть этот простой 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 проходит обычный «неинициализированный», «загружаемый», «полный» цикл, никаких ошибок не выдается, ничего.

У кого-нибудь есть идеи о том, что я делаю неправильно? Полностью потерялся здесь.

6
задан Dimitar Velitchkov 5 December 2011 в 20:57
поделиться