2011-12-05 20 views
6

Ho bisogno di rendere una pagina HTML lato server e "estrapro" i byte grezzi di un elemento canvas in modo che possa salvarlo in un PNG. Il problema è che l'elemento canvas è stato creato da javascript (sto usando il Flot di jquery per generare un grafico, in pratica). Quindi suppongo di aver bisogno di un modo per "ospitare" la funzionalità DOM + Javascript da un browser senza utilizzare effettivamente il browser. Ho optato per mshtml (ma aperto a tutti e tutti i suggerimenti) in quanto sembra che dovrebbe essere in grado di farlo esattamente. Questo è un progetto MVC ASP.NET.Rendering HTML + Javascript lato server

Ho cercato in lungo e in largo e non ho visto nulla di conclusivo.

così ho questo semplice HTML - ad esempio mantenuto il più semplice possibile per dimostrare il problema -

<!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> 

che produce l'uscita prevista quando viene eseguito da un browser.

Desidero essere in grado di caricare l'HTML originale in memoria, eseguire la funzione javascript e quindi manipolare l'albero DOM finale. Non riesco a utilizzare alcuna classe System.Windows.WebBrowser, poiché il mio codice deve essere eseguito in un ambiente di servizio.

Quindi, ecco il mio codice:

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; 

Il problema è, "beforeScript" e "afterScript" sono esattamente gli stessi. L'istanza IHTMLDocument2 passa attraverso il normale ciclo "non inizializzato", "carico", "completo", senza errori, niente.

Qualcuno ha qualche idea su cosa sto facendo male? Completamente perso qui.

risposta

1

ho trovato Awesomium Does esattamente quello che mi serve! "Struttura del browser Web senza finestre". Brillante.

1

Fondamentalmente si sta tentando di fare cose che non devono essere fatte in questo modo.

Generate HTML + Javascript per consentire al browser di disegnarlo. Scrivi C# per abilitare qualsiasi tipo di cose lato server.

Generazione di HTML + Javascript sul server per caricarlo in un browser sul server per poter salvare i suoni PNG errati.

Hai pensato ad altri approcci come la generazione dell'immagine utilizzando il componente C# lato server? Fondamentalmente, perché hai davvero bisogno di salvarlo sul server? Forse qualcuno può fornire una soluzione migliore?

+0

Grazie per aver dedicato del tempo per rispondere, ma non saranno d'accordo con quello che hai detto - in materia di "non destinato ". L'area visibile di un browser (la finestra) dovrebbe essere (ed è) separata dal suo motore DOM/Javascript interno. Perché dovrebbe importare dove viene visualizzato il risultato? Perché non è possibile eseguire il rendering di DOM + CSS + Javascript in qualsiasi posizione in memoria? In effetti, c'è un esempio di Node.js che interagisce con Flot per fare esattamente quello che voglio fare: generare un grafico sul lato server. Purtroppo, non posso usare Node.js ... –

+0

Per quanto riguarda ciò che devo fare sul server - Ho bisogno, periodicamente, di produrre un grafico (per ora, usando Flot) in un ambiente senza testa e non interattivo. Il grafico deve apparire esattamente come se un utente stesse visualizzando la pagina web in un browser. Questo è un progetto ASP.NET MVC, non ho trovato alcun controllo/componente sul lato server per farlo facilmente. –

+0

Sì, praticamente hai ragione. Ha davvero senso rendere DOM + CSS + Javascript ovunque nella memoria. Tuttavia, mi aspetto che questo funzioni con un browser, che non può essere caricato in una sessione non interattiva. Comunque, ti auguro buona fortuna, se procederai con questo. –

1

È possibile considerare l'utilizzo di Watin. Genera la tua pagina quindi usa Watin api per catturare la pagina generata.

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

+0

Ho provato Watin. È bello, ma sembra essere solo un involucro attorno a IE/Firefox e in realtà li avvia, come in una finestra separata di processo +. Quindi, non va bene in un ambiente senza testa, non interattivo. –

Problemi correlati