xmlHttpRequest.onerror handler use case - javascript

What sort of situations could cause this handler to be called? I'm not finding any instance where this method throws an error.
I tried with the device offline, I get xmlHttpRequest.status = 0 but no error.
Question is what sort of situations can I create in order to test functionality of this handler.
var xmlhttp = new XMLHttpRequest(),
method = 'GET',
url = 'https://developer.mozilla.org/';
xmlhttp.open(method, url, true);
xmlhttp.onerror = function () {
console.log("** An error occurred during the transaction");
};
xmlhttp.send();
From: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequestEventTarget/onerror

Your question is the perfect example. Just try your code from your web developer console while on this very page.
Here, try it yourself:
var xmlhttp = new XMLHttpRequest(),
method = 'GET',
url = 'https://developer.mozilla.org/';
xmlhttp.open(method, url, true);
xmlhttp.onerror = function () {
console.log("** An error occurred during the transaction");
};
xmlhttp.send();
When dealing with any network based IO all kinds of things could happen. Cross-Origin requests are only one. What if the server is offline, DNS lookup fails, a router between you and the server that is critical point of failure goes down?

Since an XHR call is for a server response, onerror would come into play when there is an error at the server. Changing your client to be offline doesn't simulate a server error.
Suppose the server resource gets moved and the server responds with a 404 error? What if the server times out? What if the request itself is malformed and causes the server to throw an error?

Related

How do you handle an "Access to restricted URI denied" error in JavaScript when using XMLHttpRequest?

I have the following code:
var req = new XMLHttpRequest();
req.onload = function(){
if (req.status === "200"){
doSomethingWithTheReceivedData();
}
else {
alert("Error msg");
}
};
However when running index.html directly from my computer (when it isn't being served from my server) I get "NS_ERROR_DOM_BAD_URI: Access to restricted URI denied" in the Firefox web console of course because the relative path that the script is trying to access isn't available on my computer (it is on my server).
Now I want to handle this error correctly, because currently when a user clicks the button that triggers this code nothing happens. I already added the status code check, but that doesn't seem to work for handling this error, I assume a request is never returned? So how do I handle such an error?
Use a try-catch when you send the request:
try{
req.send(null);
}catch(e){
alert(e.message);
}

XMLHttpRequest, send and security restrictions

I thought I could catch an error in send like this
try {
xhr.send();
} catch(e) {
// fix-me: With the
// bookmarklet on a https page
// you can't even send a HEAD
// request due to security
// restrictions. Check for
// this case here.
console.log("xhr.send, e=", e, method, window.location.href, url)
debugger;
}
console.log("I am here now");
However I never get to that console.log statement in the catch block after xhr.send.
In the console I instead get a message like this.
Mixed Content: The page at 'about:blank' was loaded over HTTPS,
but requested an insecure XMLHttpRequest endpoint 'http://m.org/'.
This request has been blocked; the content must be served over HTTPS.
I am here now.
Is it supposed to work this way? (I am using Google Chrome.)
Is there any way to find out that there was an error? (Except looking in the console. ;-) )
UPDATE
#giuscri added the very good question if I did consider that this is async. I actually missed that it could be, but it is not. A bit surprisingly. ;-)
Please see the this example. It contains this code:
var url = "http://nowhere.org/";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
console.log("onreadystatechance, readyState=", xhr.readyState);
};
xhr.onprogress = function(event) {
console.log("onprogress, readyState=", xhr.readyState);
console.log("onprogress, event=", event);
};
xhr.onerror = function(event) {
console.log("onerror, readyState=", xhr.readyState);
console.log("onerror, event=", event);
};
var method = "HEAD";
xhr.open(method, url, true);
try {
xhr.send();
} catch(e) {
console.log("xhr.send, e=", e, method, window.location.href, url);
}
console.log("After send");
When you run this page from https:// (as in the link above) the onerror function is not run. If you run the same example from file:// then onerror is run.
Connecting from HTTPS to HTTP URIs drops the security given by the underlying encryption. Web browsers blocks such requests until explicitly allowed by the user in order to prevent data leakage over plaintext connections. Further, there is also a change in origin (scheme, domain, port).
I allowed Mixed Content for the page you linked and I got the error about the different origin in console. Looks like the code works.
By the way, support for synchronous requests using XMLHttpRequest is deprecated, because it blocks user interaction until the request completes.

Load error is not captured by try catch block

I have a code like:
try{
...
} catch(error){
...
};
In try block, there is a function call that makes a request to a server. When there is no resource on the server, an error is raised (as I can see in Google Chrome's developers tool):
Failed to load resource: the server responded with a status of 404 (Not Found)
and I am trying to catch it in the catch block, but the error is not captured.
Is it a feature of JavaScript that load error is not captured by try catch block?
Typically, when requesting information from a server (for instance, via ajax, by setting the src of an img element, etc.), you don't get an exception, but you do get an error event or callback, not least because the code doing the request finishes before the request does, so it's impossible to throw an exception at that point. Since you haven't shown how you're requesting the information, it's impossible to be more specific, but this is why you're not getting an exception.
For instance, with an ajax request, if there's an error you see the ajax request complete but with the statusCode of the XMLHttpRequest object being an error status code, rather than 200. E.g.:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
// The request is complete; did it work?
if (xhr.statusCode >= 200 && xhr.statusCode < 300) {
// Yes
}
else {
// No, got a code outside the 2xx range
}
}
};
xhr.open("GET", "/your/url/here", true);
xhr.send();

Javascript: How to catch error on page navigated to using window.location.href = url

I am using a REST service to generate a CSV file that I want to prompt the user to download. An example of the service is below:
https://localhost:8444/websvc/exportCSV?viewId=93282392
To prompt the user to download the file, I use this code:
window.location.href = exportUrl, where exportUrl would be a URL like the one above.
This works great if there are no errors on the server when executing the service. The file download prompt appears, the page doesn't refresh, and all is well.
However, if there is an error, I'm getting a nasty HTTP Status 500 page, which is no good for user experience. What I'd like to do is catch any error on the resulting page, and throw up a more friendly error without leaving the current page. I tried:
try {
window.location.href = exportUrl;
}
catch (e) {
alert(e);
}
But that doesn't seem to change the behavior at all. Does anyone have any ideas on how to handle this?
Thanks very much.
Catching an error like that will only catch a JavaScript error. That's not what you're experiencing here. Your server is returning a status code of 500. You need to make sure that everything is good BEFORE you send your users there.
To do that you could effectively 'ping' the URL with Ajax to ensure that it won't return a 500 error.
Something like the following:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
window.location.href = exportUrl;
}
}
xhr.open('head',exportUrl);
xhr.send(null);
This would do a HEAD request to the URL to ensure that there are no nasty server errors waiting.
Of course, if in the process of actually GENERATING the CSV your server throws an error - it would still return a 500.
A more robust way would be to get the data via Ajax, build a data URL via base64encode and then set window.location.href to that data URL.
By doing that, you could also ensure that the Ajax didn't return a 500 and you got the data you were expecting in the response.
Hope this helps!

XMLHttpRequest receiving no data or just "undefined"

i try to make a Firefox Addon which runs a XMLHttp Request in Javascript. I want to get the data from this request and send it to *.body.innerhtml.
That's my code so far...
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://xx.xxxxx.com", true);
xhr.send();
setTimeout(function() { set_body(xhr.responseHtml); }, 6000);
Instead of receiving the data, I get "undefined". If I change xhr.responseHtml to responseText I get nothing. I don't know why I'm getting nothing. I'm working on Ubuntu 12.04 LTS with Firefox 12.0.
If you need any more details on the script please ask!
Update:
set_body Function
document.body.innerHTML = '';
document.body.innerHTML = body;
document.close();
Update SOLVED:
I had to determine the RequestHeaders (right after xhr.open):
xhr.setRequestHeader("Host", "xxx");
For following Items: Host, Origin and Referer. So it seems there was really a problem with the same origin policy.
But now it works! Thanks to all!
when you set the last param of open to true you are asking for an async event. So you need to add a callback to xhr like so:
xhr.onReadyStateChange = function(){
// define what you want to happen when server returns
}
that is invoked when the server responds. To test this without async set the third param to false. Then send() will block and wait there until the response comes back. Setting an arbitrary timeout of 6 seconds is not the right way to handle this.
This code should work:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
set_body(xhr.responseText);
}
};
xhr.open("GET", "http://xx.xxxxx.com", true);
xhr.send();
Make sure that you are getting a correct response from URL http://xx.xxxxx.com. You may have a problem with cross-domain calls. If you have a page at domain http://first.com and you try to do XMLHttpRequest from domain http://second.com, Firefox will fail silently (there will be no error message, no response, nothing). This is a security measure to prevent XSS (Cross-site scripting).
Anyway, if you do XMLHttpRequest from a chrome:// protocol, it is considered secure and it will work. So make sure you use this code and make the requests from your addon, not from your localhost or something like that.

Categories

Resources