Potrzebuję renderować strony HTML po stronie serwera i "wyodrębnić" surowe bajty elementu canvas, aby móc go zapisać do PNG. Problem polega na tym, że element canvas jest tworzony z javascript (używam Flot jquery'ego do generowania wykresu, w zasadzie). Sądzę więc, że potrzebuję sposobu na "hostowanie" funkcjonalności DOM + Javascript z poziomu przeglądarki bez korzystania z przeglądarki. Zdecydowałem się na mshtml (ale otwarty na wszelkie sugestie), ponieważ wydaje się, że powinien on być w stanie dokładnie to zrobić. To jest projekt ASP.NET MVC.Renderowanie HTML + Javascript po stronie serwera
Szukałem dużo i nie widziałem niczego rozstrzygającego.
Więc mam ten prosty HTML - przykład przechowywane tak proste, jak to możliwe w celu wykazania problemu -
<!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>
która produkuje oczekiwany wynik po uruchomieniu z poziomu przeglądarki.
Chcę móc załadować oryginalny HTML do pamięci, wykonać funkcję javascript, a następnie manipulować ostatecznym drzewem DOM. Nie mogę używać żadnej klasy System.Windows.WebBrowser, ponieważ mój kod musi działać w środowisku usługowym.
Więc tutaj jest mój kod:
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;
Problem polega na tym, "beforeScript" i "afterScript" są dokładnie takie same. Instancja IHTMLDocument2 przechodzi przez normalny cykl "niezainicjowany", "ładowanie", "ukończenie", nie są zgłaszane żadne błędy, nic.
Ktoś ma jakieś pomysły na temat tego, co robię źle? Całkowicie zagubiony tutaj.
Dzięki za poświęcenie czasu, aby odpowiedzieć, ale nie zgadzam się z tym, co pan powiedział - o „nieprzeznaczone ". Obszar podglądu przeglądarki (okno) powinien być (i jest) oddzielny od wewnętrznego mechanizmu DOM/JavaScript. Dlaczego ma znaczenie, gdzie wynik jest renderowany? Dlaczego JavaScript DOM + CSS + nie może być renderowany w jakiejkolwiek lokalizacji w pamięci? W rzeczywistości istnieje przykład Node.js wchodzący w interakcje z Flotem, aby wykonać dokładnie to, co chcę zrobić - wygenerować stronę serwera mapowego. Niestety, nie mogę używać Node.js ... –
Jeśli chodzi o to, co muszę zrobić na serwerze - muszę okresowo tworzyć wykres (na razie za pomocą Flota) w bezgłowym, nieinteraktywnym środowisku. Wykres musi wyglądać dokładnie tak samo, jak gdyby użytkownik przeglądał stronę w przeglądarce. To jest projekt ASP.NET MVC, nie znalazłem żadnych kontroli/składników po stronie serwera, aby to zrobić w prosty sposób. –
Tak, w zasadzie masz rację. Naprawdę ma sens renderowanie DOM + CSS + Javascript w dowolnym miejscu w pamięci. Oczekuję jednak, że będzie to działać z przeglądarką, której nie można załadować w sesji nieinteraktywnej. W każdym razie życzę ci powodzenia, jeśli będziesz kontynuował to. –