I need to render an HTML page server-side and "extract" the raw bytes of a canvas element so I can save it to a PNG. Problem is, the canvas element is created from javascript (I'm using jquery's Flot to generate a chart, basically). So I guess I need a way to "host" the DOM+Javascript functionality from a browser without actually using the browser. I settled on mshtml (but open to any and all suggestions) as it seems that it should be able to to exactly that. This is an ASP.NET MVC project.
I've searched far and wide and haven't seen anything conclusive.
So I have this simple HTML - example kept as simple as possible to demonstrate the problem -
<!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>
which produces the expected output when run from a browser.
I want to be able to load the original HTML into memory, execute the javascript function, then manipulate the final DOM tree. I cannot use any System.Windows.WebBrowser-like class, as my code needs to run in a service environment.
So here's my code:
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;
The problem is, "beforeScript" and "afterScript" are exactly the same. The IHTMLDocument2 instance goes through the normal "uninitialized", "loading", "complete" cycle, no errors are thrown, nothing.
Anybody have any ideas on what I'm doing wrong? Completely lost here.
You can consider using Watin. Generate your page then use Watin api to capture the generated page.
http://fwdnug.com/blogs/ddodgen/archive/2008/06/19/watin-api-capturewebpagetofile.aspx
I found Awesomium Does exactly what I need! "Windowless web-browser framework". Brilliant.
Basically you are trying to do things, which are not intended to be done in that way.
You generate HTML + Javascript to enable the browser to draw it.
You write C# to enable any kind of server side things.
Generating HTML + Javascript on server to load it into a browser on server to be able to save PNG sounds bad.
Did you think about other approaches like generating the image using server side C# component?
Basically, why do you really need to save it on server? Maybe somebody can provide better solution?
See Generating HTML Canvas image data server-side? for a PhantomJs solution (similar to Node.js, but different, single file, no install)
Related
I'm working on text game project in Python. Currently i have finished console app + sqlite database. Now I want to convert console app to web app - it will be the first web app in my life.
I want to create a simple GUI. With main logo, background image, several buttons and text zones. Example of simple GUI project:
simple gui project
I would like the logic of the application to be based on the code already created for console application. For example, by replacing the current console functions (for example print) with a function that returns data in the form of JSON. But without changing the internal logic of the function already written in Python. Is it possible?
What is the easiest way (and what technologies?) to do that?
converting a python application to a web application is not a very practical task in some cases.
I think you should use something like Flask or Django but if you don't want to complicate your life too much, there may be an alternative, and it's called PyPy.js
The first things that you must take into account in the logic of web applications, is that HTML is the skeleton of what you are going to show, so you must study it, Javascript adds dynamism to your page, such as animations and data updates without reloading the page, and the CSS to add styles to your html tags.
<head>
<script src="http://pypyjs.org/pypyjs-release/lib/Promise.min.js"></script>
<script src="http://pypyjs.org/pypyjs-release/lib/FunctionPromise.js"></script>
<script src="http://pypyjs.org/pypyjs-release/lib/pypyjs.js"></script>
</head>
<body>
<script type="text/javascript">
pypyjs.exec(
// Run Python code
'y = "hellow" '
).then(function() {
// transferring the variables we need to Javascript, in this case only 'y'.
return pypyjs.get('y');
}).then(function(result) {
// Display an alert like print in Python
alert(result);
});
</script>
</body>
that would be the same as ...
y = "hellow"
print (y)
I am currently having a size issue when I create a graph using bokeh.
I write my python/bokeh script and export the result to an html file. It works fine.
However, I have so much data that the final html file is around 30Mb.
It loads on the web browser but it takes a long time (1min).
That is not very practical if I was to deploy it on the web.
Opening the html file, I see that the 30Mb of data are embedded in:
<script type="application/json" id="myID">
and this is later called with:
<script type="text/javascript">
(function() {
var fn = function() {
Bokeh.safely(function() {
(function(root) {
function embed_document(root) {
var docs_json = document.getElementById('myID').textContent;
I was wondering if it was possible to either create an external json and load it more efficiently (compress? using XMLHttpRequest()? using Ajax? buffering?)
So far I have found posts like:
Loading large json files (250mb+) with XMLHttpRequest, and javascript library such as 'oboejs' (http://oboejs.com/)
but I was not unable to achieve something.
Since I do not have any experience with javascript maybe I am missing something obvious.
Thank you in very much in advance for your help.
In the object element with the ID x a text file is loaded and displayed correctly. How can I get this text with JavaScript?
I set
y.data = "prova.txt"
then tried
y.innerHTML;
y.text;
y.value;
None of these work.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<object id="x" data="foo.txt"></object>
<script>
var y = document.getElementById("x")
</script>
</body>
</html>
I'm afraid this isn't going to be easy as you'd like it to be.
According to your comments, you tried AJAX first, but came across CORS problems. This happens when you try to include data from files on a different domain name.
Since that didn't work, you tried to include the file inside an object tag. This works a bit like an iframe - the data will be displayed on the webpage, but for the same reasons as above, you cannot access the data through JavaScript if the file is under a different domain name. This is a security feature. That explains the error you were getting most recently:
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLObjectElement'
Now, there are a few ways you might be able to get around this.
Firstly, if this is a program exclusively for your own use, you can start your browser with web-security disabled (though this is dangerous for browsing the web generally). In Chrome, for example, you can do this by launching Chrome with the --disable-web-security flag. More details here.
Secondly, you can try to arrange that your document and the file do belong under the same domain. You will probably only be able to do this if you have control of the file.
Your error message (specifically a frame with origin "null") makes me think that you are running the files directly in the web-browser rather than through a server. It might make things work better if you go through an actual server.
If you've got Python installed (it's included on Linux and Mac), the easiest way to do that is to open up the terminal and browse to your code's directory. Then launch a simple Python server:
cd /home/your_user_name/your_directory
python -m SimpleHTTPServer
That will start up a web server which you can access in your browser by navigating to http://localhost:8000/your_file.html.
If you are on Windows and haven't got Python installed, you could also use the built-in IIS server, or WAMP (or just install Python).
y.innerHTML = 'Hello World';
will replace everything in the 'x' element with the text 'Hello World', but it looks like you've already loaded another HTML document into the 'x' element. So the question is...
Where exactly in the 'x' element do you want to insert the text? for example 'x' -> html -> body?
The object element is loading the text file asynchronously, so if you try to get its data by querying the element, you'll get undefined.
However, you can use the onload attribute in <object> elements.
In your HTML, add an onload that calls a function in your script to catch when the text file has fully loaded.
<object id="x" onload="getData()" data="readme.txt"></object>
In the script, you can get the object's data with contentDocument.
function getData() {
var textFile = document.getElementById('x').contentDocument;
/* The <object> element renders a whole
HTML structure in which the data is loaded.
The plain text representation in the DOM is surrounded by <pre>
so we need to target <pre> in the <object>'s DOM tree */
// getElementByTagsName returns an array of matches.
var textObject = textFile.getElementsByTagName('pre')[0];
// I'm sure there are far better ways to select the containing element!.
/*We retrieve the inner HTML from the object*/
var text = textObject.innerHTML;
alert(text); //use the content!
}
I am testing the Signature Pad plugin by Thomas J Bradley and have it working and am able to convert the JSON signature to PNG using PHP but would like to be able to convert the JSON signature to PNG using C#.
There is a supplimental class for doing this called SignatureToImageDotNet which I have not been able to get to work. I should mention that I am new to ASP.NET / C#. So far I have created a website in Webmatrix and have the signature capture form up and running and can return the outputed JSON to a page but am unable to convert it to a PNG image. I've created an 'App_Code' folder and put the 'SignatureToImage.cs' file in it but I'm not sure how to call it.
I'm sure this would be very trivial for someone with ASP.NET / C# experience and I'm hoping someone has done this before or could do it and let me know exactly how to do it as the documentation is very brief.
You did the right thing in creating the App_Code folder, usually people miss that part. As far as calling the class, ASP.NET Web Pages works pretty much like PHP. You create a code block at the top of a cshtml page, which executes when the page is loaded:
http://www.asp.net/web-pages/tutorials/introducing-aspnet-web-pages-2/getting-started
Depending on what else you're doing in the request (I would need a little more info / code), my guess is you can just start to use the SignatureToImage class inside of a razor block at the top of the page:
default.cshtml
#{
if (IsPostback) {
var sigToImg = new SignatureToImage();
var signatureImage = sigToImg.SigJsonToImage(signatureJson);
// do something with the image!
}
}
<html>
....
I know the answer is a little open ended, but please feel free to ask my an questions about how Web Pages or C# works, if you have something more specific.
It's been almost three weeks and I'm Googling around. my eyes got tired and headaches was included too.
I couldn't do it what even 8-10 hours daily computing :(
I have some data that saved in a valid XML file on the server(domain or sub-domain)
I've choosed XML because I'm may or probably need it for other future application use.
What I want to do is:
1- including the XML file and load it on a client side HTML page.(does sub-domain or normal domain make a difference while including?)
2- I do prefer using JavaScript (or Vb Script) or any other client side script(if available) for parsing or manipulating thing.
And If you do prefer me a better way to include a server side XML file including....I'm listening
EDIT:
I'm working on AJAX now but why I can't get data from a URL?
something like:
xmlhttp.open("GET","https://www.mywebsite.com/xmlfile.xml",true);
buy it's not working :(
Because you haven't given the actual code that you're using, I am guessing here and have put together an HTA that you can try. This only works on Windows (as I believe that is the platform you're targeting). Copy this code into a text file and save it with a .hta file extension:
<html>
<head>
<title>HTA Ajax Example</title>
<script type="text/javascript">
var ajaxRequest = function() {
var http = new ActiveXObject('MSXML2.XMLHTTP');
http.onreadystatechange = function() {
if(http.readyState === 4 && http.status === 200) {
var div = document.getElementById('target-div');
div.innerHTML = http.responseText;
}
}
http.open('GET', 'http://www.w3schools.com/ajax/ajax_info.txt', true);
http.send();
return true;
}
</script>
</head>
<body>
<div id="target-div"></div>
<input type="button" value="load" onclick="ajaxRequest();"></input>
</body>
</html>
On clicking the Load button, the text from your w3schools example will be loaded into the page. This should get you started. Should you want to provide a cross-platform solution, a library like jQuery will handle all the differences for you.
As mentioned before, the url used in the request is a full url to a resource on a different server. This won't work if you put this code on a server because of the cross-domain security issue.
If you want to pick up information from an XML file, you might want to use http.responseXML rather than http.responseText. The former property makes the response available as an XML document object rather than a text string.
including the xml file and load it on a client side html page.
Use Ajax, and use a library to access it.
does sub-domain or normal domain make a difference while including?
If it is different to the page: yes
Can you use AJAX? http://www.w3schools.com/ajax/default.asp