javascript - strange debugging issue - javascript

My code changes are not being reflected in IE or FF.
In IE:
I commented out the alert('start'), but I still see the alert when I stop-restart my visual studio debugger.
In FF:
Same code change, but none of the alerts show at all. I uncommented alert('start') and I still dont see it in FF.
I tried setting my port to stay fixed at 5204. I also stopped the ASP.NET development server prior to starting the debugger again. Still doesnt help.
Environment: VS 2010 IE7 and FF3.6.
Code
simplexhr = {
doxhr: function (container, url) {
//alert("START");
if (!document.getElementById || !document.createTextNode) {
alert("NO JS SUPPORT");
return;
}
simplexhr.outputContainer = document.getElementById(container);
if (!simplexhr.outputContainer) {
alert("NO OUTPUT CONTAINER");
return;
}
var request;
try {
//alert("Mozilla AJAX");
request = new XMLHttpRequest();
alert(request);
}
catch (error) {
try {
//alert("IE AJAX");
request = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (error) {
return true;
}
}
request.onreadystatechange = function () {
if (request.readyState == 1)
simplexhr.outputContainer.innerHTML = 'loading...';
}
alert("made it to try AJAX");
request.open('get', url);
//alert("ready state: " + request.readyState);
}
}
UPDATE
On further testing, this problem is due to caching. But, it only happens when I use "unobtrusive javascript" or javascript inside its own *.js file linked in the header:
<script src="Scripts/simpleXHR.js" type="text/javascript"></script>
Moving the code into the page - viewing source - the javascript updates everytime with no caching issues. So is there a better way to perform "unobtrusive javascript"? Or should it be renamed "unproductive javascript" :P

Sounds like it might be a browser cache issue. Try clearing your cache in each browser. Hopefully that will pick up the changes.
You could verify that by doing a view-source in the browser and see if you're actually getting the latest code.

Related

How to catch silent NS_ERROR_OUT_OF_MEMORY in Chrome

I tested the loading of very large files with XMLHttpRequest and noticed an interesting behavior of Chrome (90.0.4430.212): It loads the full file, but finishes with a 200-OK code and and empty (!) result. First I thought it was a silent timeout or whatever, but no, it seems to be a reached memory limit.
Trying it in Firefox (13.0esr (64-bit)) took for ages, but in the end I knew more: The Transfer itself did not trigger an "error" or a "timeout" event, resulted with 200 and empty result as well. But it threw an error:
Exception { name: "NS_ERROR_OUT_OF_MEMORY", message: "", result: 2147942414, filename: "http://localhost/testcenter-backend/vo_data/teterei.html", lineNumber: 16, columnNumber: 0, data: null, stack: "transferComplete#http://localhost/testcenter-backend/vo_data/teterei.html:16:9\n" }
So it has nothing to do with the transport itself, but apparently a memory limit reached when trying to do anything with the result. When I don't use the oReq.response, the error does not appear.
Okay, how to handle this? In Firefox I can catch the error with a simple try catch block. But this does not work for Chrome. A naive approach would be just to check if the resulting content is empty, but I wonder if there is another possibility to detect this stuff happening.
--
How to reproduce:
Create a huge file.
I generated a 10,4GB file this way:
dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*10000]
Run this code in a browser to load it.
const oReq = new XMLHttpRequest();
function updateProgress (oEvent) {
console.log("progress", oEvent.loaded);
}
function transferComplete(evt) {
console.log("The transfer is complete.", oReq.getAllResponseHeaders(), oReq.status);
console.log(oReq.response); // here too much memory is allocated
}
function transferFailed(evt) {
console.log("error", oReq.getAllResponseHeaders(), oReq.status);
}
function transferCanceled(evt) {
console.log("cancel", oReq.getAllResponseHeaders(), oReq.status);
}
function timeOut(evt) {
console.log("timeout", oReq.getAllResponseHeaders(), oReq.status);
}
oReq.addEventListener("progress", updateProgress);
oReq.addEventListener("load", transferComplete);
oReq.addEventListener("error", transferFailed);
oReq.addEventListener("abort", transferCanceled);
oReq.addEventListener("timeout", timeOut);
// your huge file here instead
oReq.open("GET", "https://cdn.jsdelivr.net/npm/jquery#3.2.1/dist/jquery.min.js"); // URL to huge file here
oReq.send();
The actual memory limit may vary to your system.

Handling the browser's window / tab close event in javascript [duplicate]

This is the code which i used for window.onbeforeunload
<head>
<script>
window.onbeforeunload = func;
function func()
{
var request = new XMLHttpRequest();
request.open("POST", "exit.php", true);
request.onreadystatechange = stateChanged;
request.send(null);
}
function stateChanged()
{
if (request.readyState == 4 || request.readyState == "complete")
alert("Succes!");
}
</script>
</head>
this works with IE and Mozilla but does not work with Chrome..... please help......
thanks in advance.....
It seems that the only thing you can do with onbeforeunload in recent version of Chrome is to set the warning message.
window.onbeforeunload = function () {
return "Are you sure";
};
Will work. Other code in the function seems to be ignored by Chrome
UPDATE: As of Chrome V51, the returned string will be ignored and a default message shown instead.
Know I'm late to this, but was scratching my head why my custom beforeunload message wasn't working in Chrome and was reading this. So in case anyone else does the same, Chrome from Version 51 onwards no longer supports custom messages on beforeunload. Apparently it's because the feature has been misused by various scams. Instead you get a predefined Chrome message which may or may not suit your purposes. More details at:
https://developers.google.com/web/updates/2016/04/chrome-51-deprecations?hl=en#remove-custom-messages-in-onbeforeload-dialogs
Personally do not think the message they've chosen is a great one as it mentions leaving the site and one of the most common legitimate uses for onbeforeunload is for dirty flag processing/checking on a web form so it's not a great wording as a lot of the time the user will still be on your site, just have clicked the cancel or reload button by mistake.
You should try this:
window.onbeforeunload = function(e) {
e.returnValue = 'onbeforeunload';
return 'onbeforeunload';
};
This works on latest Chrome. We had the same issue the e.returnValue with value of onbeforeunload solved my problem.
Your code should be like this:
<head>
<script>
window.onbeforeunload = function(e) {
e.returnValue = 'onbeforeunload';
func();
return ''onbeforeunload'';
};
function func()
{
var request = new XMLHttpRequest();
request.open("POST", "exit.php", true);
request.onreadystatechange = stateChanged;
request.send(null);
}
function stateChanged()
{
if (request.readyState == 4 || request.readyState == "complete")
alert("Succes!");
}
</script>
</head>
Confirmed this behavior on chrome 21.0.1180.79
this seems to work with the same restritions as XSS, if you are refreshing the page or open a page on same domain+port the the script is executed, otherwise it will only be executed if you are returning a string (or similar) and a dialog will be shown asking the user if he wants to leans or stay in the page.
this is an incredible stupid thing to do, because onunload/onbeforeunload are not only used to ask/prevent page changes.
In my case i was using it too save some changes done during page edition and i dont want to prevent the user from changing the page (at least chrome should respect a returning true or change the page without the asking if the return is not a string), script running time restrictions would be enought.
This is specially annoying in chrome because onblur event is not sent to editing elements when unloading a page, chrome simply igores the curent page and jumps to another. So the only change of saving the changes was the unload process and it now can't be done without the STUPID question if the user wants to change it... of course he wants and I didnt want to prevent that...
hope chrome resolves this in a more elegant way soon.
Try this, it worked for me:
window.onbeforeunload = function(event) {
event.returnValue = "Write something clever here..";
};
Try this. I've tried it and it works. Interesting but the Succes message doesn`t need confirmation like the other message.
window.onbeforeunload = function()
{
if ( window.XMLHttpRequest )
{
console.log("before"); //alert("before");
var request = new XMLHttpRequest();
request.open("POST", "exit.php", true);
request.onreadystatechange = function () {
if ( request.readyState == 4 && request.status == 200 )
{
console.log("Succes!"); //alert("Succes!");
}
};
request.send();
}
}
None of the above worked for me. I was sending a message from the content script -> background script in the before unload event function. What did work was when I set persistent to true (in fact you can just remove the line altogether) in the manifest:
"background": {
"scripts": [
"background.js"
],
"persistent": true
},
The logic is explained at this SO question here.
Current versions of Chrome require setting the event's returnValue property. Simply returning a string from the event handler won't trigger the alert.
addEventListener('beforeunload', function(event) {
event.returnValue = 'You have unsaved changes.';
});
I'm running Chrome on MacOS High Sierra and have an Angular 6 project whithin I handle the window.beforeunload an window.onbeforeunload events. You can do that, it's worked for me :
handleUnload(event) {
// Chrome
event.returnValue = true;
}
It show me an error when I try to put a string in event.returnValue, it want a boolean.
Don't know if it allows custom messages to display on the browser.
<script type="text/javascript">
window.addEventListener("beforeunload", function(e) {
e.preventDefault(); // firefox
e.returnValue = ''; // Chrome
});
</script>

Handling http_request in IE 8, using AJAX

i've been working on some kind of remote control for some time now and figured out a problem that confuses me:
The remote controle is supposed to control some kind of machine. The complete hardware based code is written in c by myself, but thats not really interesting for my problem.
Im using a webserver and a webpage to get access to some basic commands, just like driving forward, backward or turning motor on/off (i use a wlan accesspoint on the board in the machine to connect to it). So far everything works fine, but............:
My Problem is, that there are several options to control the functions of the machine (Terminal, wired-connected Notebook, remote control, "normal" working loop) at the same time. This means, if the machine switches on the motor by itself or a worker uses the terminal, it is neccessary for me to have a feedback on my remote control aswell (at the moment i switch the color of the different button-border from green=inactive to red=active).
The way i did that is easy explained:
If for an example the motor is switched on in c, i write a file with a decimal number that represents a binary code. Just like motor on is 0001 means i write a dec 1. Motor off would be 0010, means i write a dec 2. Because it is possible that there are more than only one function running at the same time i just pass values like 13 (motor on: 0001 = 1; forward: 0100 = 4; lights on: 1000 = 8; => 8+4+1=13). I use a binary AND comparsion to get the actual information about the status afterwards.
Nevertheless i cant refresh the page every two seconds to check the file i write to for changes, im using ajax to have a simple and fancy request possibility:
var http_request = false;
function RequestCommandStatus(url) {
http_request = false;
if (window.XMLHttpRequest) {
http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) {
alert('Ended due to an error!');
return false;
}
http_request.open('GET', url, true);
http_request.onreadystatechange = control4Commands;
http_request.send(null);
}
and after that i do the comparsion stuff:
function control4Commands() {
if (http_request.readyState == 4) {
var answer = http_request.responseText;
if ((answer & 0x1) == 0x1){
//do something
}
if ((answer & 0x2) == 0x2){
//do something
}
if ((answer & 0x4) == 0x4){
//do something
}
if ((answer & 0x8) == 0x8){
//do something
}
}
}
setInterval("RequestValveStatus('myfile.txt')", 1000);
This works pretty good in Firefox but for some reason i got a strange problem in IE8 (even if i enabled every known scripting language and allowed pretty much complete access and control):
For some reason the request seems to be executed once, but after that there is no more interaction between the page and the server. The value of the file changes like it is supposed to. If i reload the page manualy, and for an example, the motor is still running, it changes the color of the border to red. In my opinion this should make sure that the request atleast succeded once.
By using the script debugger of the developer tools, i got the error message, that the http_request.open() failed because of access denied. My first suggestion was that it might be about the path or the type of the file i read from, but i wasnt able to fix it in IE8 with .html, .php, .txt and "several" other types. Also changing the path/origin didnt solved the problem.
I'd really like to discuss this problem with you and feel free to post me your ideas about this way of getting the actual status of the functions.
Greeting,
Ohemgi
I'm sorry for my bad english. Feel free to ask if you cant follow my explanations :-)
try to change
setInterval("RequestValveStatus('myfile.txt')", 1000);
into
setInterval(function() { RequestValveStatus('myfile.txt'); }, 1000);

How to check if a chrome:// file exists via javascript, without actually loading the file?

I'm using the following function in a Firefox extension to check if a file exists in another extension:
function chromeFileExists(fileLoc) // in extension package
{
var xmlhttp = new window.XMLHttpRequest();
try {
xmlhttp.open("GET", "chrome://"+fileLoc, false);
xmlhttp.send(null);
var xmlDoc = xmlhttp.responseXML.documentElement;
}
catch(ex) {
return false;
}
return true;
}
But the problem is, of course, that if the file does exist, it actually loads the file before it tells me. Some of the files I'm querying are over 1MB in size, so I'd rather not load them into memory.
How to check for the existence and return without loading the file itself? I've tried working with onreadystatechange, but can't seem to figure it out.
I think I figured it out, after learning a few things about the way this type of request is handled:
status for local files is always "0" (not 200, etc.).
if async is true, it won't throw an exception if the file is not found.
it seems to skip readyState 3 for some reason - if async is false, readyState goes straight to 4.
if the first part of the chrome URL (the extension name) doesn't exist, it throws an exception on open().
If async is false and the file doesn't exist, it throws an exception on onreadystatechange.
If async is false and the file does exist, aborting onreadystatechange stops it from actually reading the file.
So, it seems the way to go is async=false, abort after the readyState change occurs successfully (to 4) and return true (the file exists). If there is an exception on open or onreadystatechange, return false (doesn't exist).
Here's the code, which seems to abort while xmlhttp.responseXML is still null if the file exists, and throws an exception if it doesn't:
function chromeFileExists(fileLoc) // in extension package
{
var xmlhttp = new window.XMLHttpRequest();
try {
xmlhttp.open("GET", "chrome://"+fileLoc, false);
xmlhttp.onreadystatechange=function() {
xmlhttp.abort();
}
xmlhttp.send(null);
}
catch(ex) {
return false;
}
return true;
}
You can use the onreadystatechange method of an XMLHTTPRequest and a setTimeout. I haven't actually tried this but I imagine it would go something like:
var clearhttp = function() {
xmlhttp.abort();
fileDoesNotExist = false;
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState == 3) {
setTimeout(clearhttp, 250);
} else if(xmlhttp.readyState == 4 && xmlhttp.status == 404){
fileDoesNotExist = true;
}
}
what about:
xmlhttp.open("HEAD", "chrome://"+fileLoc, false);
Probably easier for you to test than it is for me since I haven't messed with extensions in a while and you can't exactly request chrome:// from a normal page :)

Catching same origin exception in Javascript?

I'm trying to create my own XMLHttpRequest framework to learn how this things work internally.
A thing that puzzles me is that I cannot find how to catch a "Same origin" exception.
The idea behind this is that I try to load a URL, if I get a Same origin exception, I re-request the URL through a proxy script local for the script. The reason I do this is because I need to access production data from a development sandbox and I want it to be as transparent as possible for the script itself.
I know it's a bad practice but this is the least intrusive way of doing this at the moment :)
Just to clear things - I don't want to bypass same origin, I just want to catch the thrown exception so I can do something about it.
Here is the code I currently use for my xhr:
var net = function (url, cb, setts){
this.url = url;
this.cb = cb;
var oThis = this;
if (!this.xhr) {
this.xhr = new XMLHttpRequest();
this.xhr.onreadystatechange = function() {
if (oThis.xhr.readyState == 4 && oThis.xhr.status == 200) {
document.body.innerHTML += "RS: "+oThis.xhr.readyState+"; ST:"+oThis.xhr.status+"; RP:"+oThis.xhr.responseText+"<br>";
}
else {
// do some other stuff :)
document.body.innerHTML += "RS: "+oThis.xhr.readyState+"; ST:"+oThis.xhr.status+"; RP:"+oThis.xhr.responseText+"<br>";
}
}
}
this.xhr.open("GET", url,true);
this.xhr.send();
} // It's WIP so don't be scared about the unused vars or hardcoded values :)
I've tried to try...catch around xhr.send(); but no avail, still can't catch the exceptions.
Any ideas or pointers would be greatly appreciated.
xhr.onreadystatechange = function() {
if (xhr.readyState==4) {
if (xhr.status==0) {
alert("denied");
} else {
alert("allowed");
}
}
}
Are you sure it's actually supposed to throw an exception? I can't see anything in the specifications: http://www.w3.org/TR/XMLHttpRequest/#exceptions Looks like it does. My bad.
In either case, you can always check the domain of the incoming string against the domain of the page the user is currently on.
FWIW, as you can see by this jsFiddle (open up Web Inspector), Chrome doesn't really throw an exception. It just says "Failed to load resource".

Categories