WPF WebBrowser.InvokeScript() Keeps Loading Old Script - javascript

I have a very simple JavaScript file named as MyJava.htm as shown below:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
function ShowMe(message)
{
var n = message.length;
var s = a.toString();
alert("total length = " + s);
}
</script>
</head>
<body style='background-color:transparent'>
<P>Empty</P>
</body>
</html>
As you can see, there is an error in the code ('a' is undefined). I saved the file into my local machine's web server folder, which is c:\inetpub\wwwroot.
When I first run it using WPF WebBrowser control (this) as follows:
JavascriptInterface jint = new JavascriptInterface(mainWindow);
this.myBrowser.ObjectForScripting = jint;
this.myBrowser.Source = new Uri( #"http://127.0.0.1/myJava.htm");
this.myBrowser.InvokeScript("ShowMe", "Hello");
where mainWindow is a dialog. I'll get the error message saying 'a' is undefined.
Then, I went into the file MyJava.htm and corrected it (replacing variable 'a' with 'n'); saved the file; reran the WPF application.
I still get the 'a' is undefined error.
If I rename the file and change the URL accordingly, then everything works.
Apparently, the old script was being loaded even I've altered the content of the file.
How do I resolve this? How can I tell WPF (or whoever) to load the new contents from the URL?

Related

Sibling text file string to blob in JavaScript - unavailable?

I have a text file (here big_buck_bunny_trailer_480p.srt), "sibling" to a html page (so when I run the html page locally, it is a local file - when I run it on server, it is a remote file) - the directory structure is:
.
├── big_buck_bunny_trailer_480p.srt
└── ttt.html
I'm trying to read the text file using XMLHttpRequest; that succeeds fine, and I can get the string content of the text file. But when I try to create a Blob out of it, in Firefox 60 console I get "unavailable".
This is my test file, ttt.html:
<script type="text/javascript">
function reqListener () {
console.log(this.responseText);
var myblob = new Blob([this.responseText], {
type: 'text/plain'
});
console.log(myblob);
}
var oReq = new XMLHttpRequest(); // "To read files that are siblings of the HTML document, use XMLHttpRequest"
oReq.addEventListener("load", reqListener);
oReq.open("GET", "big_buck_bunny_trailer_480p.srt");
oReq.send();
</script>
When I run it in Firefox 60, console prints out:
1 ttt.html:4:3
00:00:00,005 --> 00:00:03,800
The peach open movie project presents
(...)
<unavailable> ttt.html:8:3
The character encoding of the HTML document was not declared. ...
XML Parsing Error: syntax error
Location: file:///tmp/test/big_buck_bunny_trailer_480p.srt
Line Number 1, Column 1: big_buck_bunny_trailer_480p.srt:1:1
So, I get the string right - but why is the Blob <unavailable>? How can I get a Blob out of this string?
Bonus question: I get why the warning "The character encoding of the HTML document was not declared" appears, - after all, I don't even have <html> in my html file. BUt why does XML Parsing Error: syntax error appear? All I asked for was to read this file, not parse it? If the parsing is automatic, can I prevent it somehow - all I need are the string contents?
EDIT: reduced the example to this:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript">
var myblob = new Blob([window.btoa("Hello world")], {
type: 'text/plain'
});
console.log(myblob);
</script>
</head>
</html>
... and accessed it by using python -m SimpleHTTPServer, so via http://127.0.0.1:8000/ttt.html; and the only printout I get in the console is:
<unavailable> ttt.html:22:3
So, how do I get an actual blob from a string?
your html tags may interrupt the xml parsing. That's why its throwing Syntax Error. That kind of error is very common in JSON or XML parsing. Before create Blob, encode the Response Data.
Try this,
new Blob([window.btoa(this.responseText)], {
type: 'text/plain'
});
And also, When you retrieve the data from Blob. You need to decode using window.atob().
There are many things that browsers won't allow to happen over the file:// protocol. This is probably one of them.
Instead of running it over the file:// protocol, it is better to use a small local server to run it over. There are lots of them out there, so lots of options. Many IDEs even have them built in. I like to write a quick 10-line version with Express and Node. Whichever you chose, it'll just serve up static files for you over the http:// protocol so you can avoid these issues.
Got it, finally - turns out, if you watch console.log(myblob); in Firefox 60 Browser Console (Ctrl-Shift-J, the one in standalone window), then you get <unavailable>; but if at the same time, you observe the Web Console (Ctrl-Shift-K, sits in a tab near the Inspector of Inspect Element right-click), then you get a proper printout; see .gif:
Here it is accessed via a local server, so through http://127.0.0.1:8000/ttt.html - but accessing it locally via file:// protocol yields the exact same results (the blob can be seen in Web console to be instantiated fine, regardless of protocol).
For reference, here is the final ttt.html I used while capturing the .gif video:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript">
function reqListener () {
console.log(this.responseText.substr(0,60)+"...");
var myblob = new Blob([window.btoa(this.responseText)], {
type: 'text/plain'
});
console.log(myblob);
}
var oReq = new XMLHttpRequest(); // "To read files that are siblings of the HTML document, use XMLHttpRequest"
oReq.overrideMimeType("text/plain");
oReq.addEventListener("load", reqListener);
oReq.open("GET", "big_buck_bunny_trailer_480p.srt");
oReq.send();
</script>
</head>
</html>

How do I create a JavaScript file that opens another file and prints the content of it?

I am using JavaScript locally on a Windows computer. In the folder that I put this .jsp file, I have a file named text.txt. I want this .jsp file to display the content of the file. It is as if my function is never invoked. I use a web browser to test the script. I see "JavaScript locally on Windows" as my header shows. What should I do to get my function to work? I get no error message. I searched the internet. I based my code off of this link.
<HTML>
<HEAD>
<TITLE> Javascript locally on Windows </TITLE>
</HEAD>
<BODY>
<h2>JavaScript locally on Windows</h2>
<script language="Javascript">
function readContentOfFile(file)
{
var inputFile = new XMLHttpRequest();
inputFile.open("GET", file, false);
inputFile.onreadystatechange = function ()
{
if(inputFile.readyState === 4)
{
if(inputFile.status === 200 || inputFile.status == 0)
{
var contentText = inputFile.responseText;
alert(contentText);
}
}
}
inputFile.send(null);
}
readContentOfFile(text.txt)
</script>
</BODY>
</HTML>
The error is when you pass the file name as parameter to the function.
Watch for:
inputFile.open("GET", file, false);
open is a method of the XMLHttpRequest object that expects the second parameter as a string.
Because you define this variable on the function parameter here:
function readContentOfFile(file)
You should pass the parameter as a string wrapping it in quotes:
readContentOfFile("text.txt")

Dynamically accessing changing variable from external .js file

I'm very new to javascript (c++ normally) and I think this question should be quite basic for you all.
I have a script that gets a variable defined in an external .js file and displays it using an alert.
The code in the .html file looks like this.
<html>
<head>
<title></title>
<script>
function addScript(url){
var extScript = document.createElement('script');
extScript.type = 'text/javascript';
extScript.src = url;
extScript.id = 'extScript'
//If there is already a script with the ID 'extScript'
//get rid of it
var headList = document.getElementsByTagName('head');
var scriptList = headList[0].getElementsByTagName('script');
for(var i = 0; i < scriptList.length; i++)
{
if(scriptList[i].id =='extScript')
{
document.getElementsByTagName('head')[0].removeChild(scriptList[i]);
}
}
document.getElementsByTagName('head')[0].appendChild(extScript);
}
function newNewChangeMode()
{
addScript("C:/Users/Suzaku/Documents/Javascript/controller.js");
alert("Neo controllerMode variable is reading " + controllerMode);
}
</script>
</head>
<body>
Get externally defined mode
</body>
</html>
And the file "controller.js" looks like this.
var controllerMode = 1111;
(that's it!)
When I click the link "get externally defined mode", my javascript runs and the alert is displayed correctly. Displaying "Neo controllerMode variable is reading 1111".
However, if I change the variable controllerMode's definition (in controller.js) to
var controllerMode = 2222;
,hit save, and click the the button again (without refreshing), it still alerts "Neo controllerMode variable is reading 1111". Whereas it SHOULD say "Neo controllerMode variable is reading 2222".
It would seem that this script is not being added dynamically. I need to be able to change this variable without having to refresh the .html.
Thanks in advance,
Guy
It sounds like your browser is only retrieving the cached javascript file. Make sure you go directly to your updated javascript file (controller.js) and hit F5 to ENSURE that you are loading a new version, not the cached one. Otherwise your browser will keep plugging the old, cached script (which has 1111 defined) into your script. Common problem!

Do the HtmlWindow returned from the HtmlPage.PopupWindow can .Invoke or .Eval javascript

Creating a separate PopupWindow that opens another web browser give me as return value a HtmlWindow object that is the same object type as the static "HtmlPage.Window" of the silverlight project. That object type provides the "Invoke" and "Eval" methods.
I want to evaluate a javascript that can be located on my Silverlight code in a string value (Eval) or inside the uri that I have popped up (Invoke).
Nomather script execution method I use, It fails.
For eval, it gives me an InvalidOperationException with "Eval failed." message.
For Invoke, it gives me an InvalidOperationException with "Failed to Invoke: TalkToJavaScript." message.
Is there a way to execute javascript on a PopupWindow.
The code here is a simple test. The first time that I press the button it popup the uri in a new webbrowser instance. The second time that I click, it tries to execute javascript on the destination uri window. It fails at ** "m_window.Invoke("TalkToJavaScript", "pute");"
Html code
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
function TalkToJavaScript(data) {
alert("Message received from Silverlight: " + data);
}
</script>
</head>
<body>
<div id="content" />
</body>
</html>
Silverlight Code
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (m_window == null)
{
HtmlPopupWindowOptions options = new HtmlPopupWindowOptions();
options.Left = 0;
options.Top = 0;
options.Width = 800;
options.Height = 600;
m_window = HtmlPage.PopupWindow(new Uri("http://www.visionwww.com/tests/ContentInjectionTest.html"),
"new", options);
}
else
{
m_window.Invoke("TalkToJavaScript", "test");
//m_window.Eval("alert(\"Message received from Silverlight\");");
}
}
Your is not XAP also being served from "http://www.visionwww.com/". Hence when you attempt to manipulate it with an Invoke that attempt is blocked for security reasons.

How can I run a local Windows Application and have the output be piped into the Browser

I have Windows Application (.EXE file is written in C and built with MS-Visual Studio), that outputs ASCII text to stdout. I’m looking to enhance the ASCII text to include limited HTML with a few links. I’d like to invoke this application (.EXE File) and take the output of that application and pipe it into a Browser. This is not a one time thing, each new web page would be another run of the Local Application!
The HTML/java-script application below has worked for me to execute the application, but the output has gone into a DOS Box windows and not to pipe it into the Browser. I’d like to update this HTML Application to enable the Browser to capture that text (that is enhanced with HTML) and display it with the browser.
<body>
<script>
function go() {
w = new ActiveXObject("WScript.Shell");
w.run('C:/DL/Browser/mk_html.exe');
return true;
}
</script>
<form>
Run My Application (Window with explorer only)
<input type="button" value="Go"
onClick="return go()">
</FORM>
</body>
Have the executable listen on a port following the HTTP protocol.
Then have the web page make AJAX-style HTTP requests to the local port with JAvascript.
The executable returns text.
The web page updates itself through DOM manipulation in Javascript.
Yes, this works. It is happening 5 feet away from me right now in another cubicle.
This is called CGI
Your already using WScript to launch, it can also read StdOut.
<html>
<head>
<script type="text/javascript">
function foo() {
var WshShell = new ActiveXObject("WScript.Shell");
var oExec = WshShell.Exec("ipconfig.exe");
var input = "";
while (!oExec.StdOut.AtEndOfStream) {
input += oExec.StdOut.ReadLine() + "<br />";
}
if (input)
document.getElementById("plop").innerHTML = input;
}
</script>
</head>
<body onload="foo();">
<code id="plop"></code>
</body>
</html>
It would be easier to have your EXE create a temp file containing the HTML, then just tell Windows to open the temp HTML file in the browser.

Categories