Рендеринг HTML + Javascript на стороне сервера - PullRequest
6 голосов
/ 06 декабря 2011

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

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

Ответы [ 4 ]

1 голос
/ 06 декабря 2011

Вы можете рассмотреть возможность использования Watin.Создайте свою страницу, а затем используйте Watin api для захвата созданной страницы.

http://fwdnug.com/blogs/ddodgen/archive/2008/06/19/watin-api-capturewebpagetofile.aspx

1 голос
/ 07 декабря 2011

Я нашел Awesomium Имеет ли точно то, что мне нужно!"Безоконный веб-браузер".Brilliant.

0 голосов
/ 10 февраля 2013

См. Создание HTML-данных изображения Canvas на стороне сервера? для решения PhantomJs (аналогично Node.js, но другой, один файл, без установки)

0 голосов
/ 06 декабря 2011

По сути, вы пытаетесь делать вещи, которые не предназначены для этого.

Вы генерируете HTML + Javascript, чтобы браузер мог его нарисовать.Вы пишете на C #, чтобы разрешить любые виды серверных действий.

Создание HTML + Javascript на сервере для загрузки его в браузер на сервере , чтобы иметь возможность сохранять PNG звуки.

Думали ли вы о других подходах, таких как генерация изображения с использованием серверного компонента C #?В основном, зачем вам действительно нужно сохранять его на сервере?Может быть, кто-нибудь может предложить лучшее решение?

...