2011-12-05 18 views
6

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.

Odpowiedz

1

znalazłem Awesomium Czy dokładnie czego potrzebuję! "Bezokienna architektura przeglądarki internetowej". Znakomity.

1

Zasadniczo próbujesz robić rzeczy, których nie zamierzasz robić w ten sposób.

Generujesz HTML + JavaScript, aby umożliwić przeglądarce narysowanie go. Piszemy C#, aby włączyć dowolny rodzaj rzeczy po stronie serwera.

Generowanie kodu HTML + Javascript na serwerze, aby załadować go do przeglądarki na serwerze, aby zapisać nieprawidłowy dźwięk PNG.

Czy myślisz o innych podejściach, takich jak generowanie obrazu za pomocą komponentu C# po stronie serwera? Zasadniczo, dlaczego naprawdę trzeba go zapisać na serwerze? Może ktoś może zapewnić lepsze rozwiązanie?

+0

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 ... –

+0

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. –

+0

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. –

1

Możesz rozważyć użycie Watin. Wygeneruj swoją stronę, a następnie użyj aplikacji Watin do przechwytywania wygenerowanej strony.

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

+0

Próbowałem Watin. To fajne, ale wygląda na to, że jest po prostu otoką wokół IE/Firefox i faktycznie uruchamia je, jak w oddzielnym procesie + okno. Nie ma więc dobra w bezgłowym, nieinteraktywnym środowisku. –

Powiązane problemy