Check status of a jQuery ajax request - ajax

It seems that the success, error, and complete callbacks only fire when the ajax request is able to get some response from the server.
So if I shut down the server the following error callback is not executed and the request fails silently.
$.ajax({
type: "GET",
url: "http://localhost:3000/",
dataType: "script",
success: function() {
alert("success");
},
error: function() {
alert("error");
}
});
What's the best way to throw an error when the server can't be reached at all.
Edit - From what I've tried and read it appears that jQuery's built in error handling doesn't work with JSONP, or dataType: "script". So I'm going to try setting a manual timeout.
Edit - Did a little more research and it looks like not only does the ajax error callback not work, but you can't abort an ajax request with dataType script or jsonp, and those requests ignore the timeout setting.
There is an alternative - the jquery-jsonp plugin, but it uses hidden iframes which I'd rather avoid. So I've settled on creating a manual timeout as suggested below. You can't abort the request if it times out, which means the script may still load even after the timeout, but at least something will fire if the server is unavailable.

You can use a setTimeout, and clear it with clearTimeout in the complete handler.
var reqTimeout = setTimeout(function()
{
alert("Request timed out.");
}, 5000);
var xhr = $.ajax({
type: "GET",
url: "http://localhost:3000/",
dataType: "script",
success: function() {
alert("success");
},
error: function() {
alert("error");
},
complete: function() {
clearTimeout(reqTimeout);
}
});

jQuery.ajax already has a timeout preference and it should call your error handler should the request time out. Check out the fantastic documentation which says — I’d quote it here, emphasis mine:
timeoutNumber
Set a local timeout (in milliseconds) for the request…
and:
error (XMLHttpRequest, textStatus, errorThrown) Function
A function to be called if the request fails. The function is passed three arguments: The XMLHttpRequest object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are "timeout", "error", "notmodified" and "parsererror". This is an Ajax Event.

error: function (jqXHR, textStatus, errorthrown) {
if (jqXHR.readyState == 0) {
//Network error, i.e. server stopped, timeout, connection refused, CORS, etc.
}
else if (jqXHR.readyState == 4) {
//HTTP error, i.e. 404 Not found, Internal Server 500, etc.
}
}
Use readyState of XMLHttpRequest to determine the status of the ajax request.
'readyState' holds the status of the XMLHttpRequest.
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready

If I remember correctly, jQuery throws exceptions. Thus, you should be able to work with a try { ... } catch() { ... } and handle it there.

You can use Jquery's AjaxSetup to handle your error handling.
$.ajax({
type: "GET",
url: "http://localhost:3000/",
dataType: "script",
success: function () {
alert("success");
}, error: function () {
alert("error");
}
//AJAX SETUP "error"//
$.ajaxSetup({
"error": function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest + ' ' + textStatus + ' ' + errorThrown); //however you want
}
});

in ie8,can use:
success: function(data, textStatus, XMLHttpRequest) {
if("success"==textStatus&&XMLHttpRequest){
alert("success");
}else{
alert("server down");
}
}
but it's can't work on chrome,firefox...
i tried

Related

Express res.jsonp returns two callback names to Safari Extension AJAX call

I'm building an extension in Safari, using Express.js on the back end. I make an AJAX call to the server, and the server responds with what appears to be a double callback name:
jQuery191026131771644577384_1364321159940 && jQuery191026131771644577384_1364321159940([
{
"foo": "bar"
}
]);
Here's the AJAX:
$.ajax({
type : "GET",
data : { 'something': 'something more'},
url : "http://localhost:3001/api/login/?callback=?",
dataType: 'jsonp',
success: function(data, text){
console.log(data)
},
error: function (request, status, error) {
console.log("ERROR: " + status + error );
}
});
...and here's the Express.js:
app.get('/api/login', function(req, res){
res.jsonp([{'foo':'bar'}]);
});
The browser is reporting a parse error, likely because of the double callback stamp above.
Clues?
It's not a double callback, it's the same as doing func && func(), it just makes sure that the function exists before calling it, so avoid throwing an exception.
Hector has it right in the comments: Try removing callback=? from the URL

Returning Json from controller, never a success

I'm successfully posting to my controller with the following code, however, success is never being hit only error. What am I doing wrong?
JS:
$.ajax({
url: '/Home/Subscribe',
type: 'POST',
dataType: 'json',
data: { email: $('#sube').val() },
success: function (data) {
// get the result and do some magic with it
alert(data.foo);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
Controller:
[HttpPost]
public JsonResult Subscribe(string email)
{
return Json(new { foo = "bar", baz = "Blech" });
}
In IE, press F12 to open developer tools. Go to Network tab and click on Start Profiler. Send a request to your Subscribe action - in a list below you will see details of sent request and returned status code. Double click on request to see details - you can then see body of your response. If the request failed with a server error, you will see that error in a body of your response.
One wrong thing I see with your code is that you have hardcoded the url:
url: '/Home/Subscribe'
You should never do this. You should always use url helpers when generating urls in an ASP.NET MVC application:
url: '#Url.Action("Subscribe", "Home")'
Also you are saying that the error callback is always hit but you didn't say what you observed in FireBug or Chrome Developer toolbar when you tried to analyze the AJAX request. If you had done this you would have seen the exact cause of failure for the request because you would have seen what request is sent to the server and what response does the server sends back to the client.
The following is my jQuery ajax snippet that works. Your controller looks right. I assume you have verified it is actually getting called by using a breakpoint.
var p = {
email: $('#sube').val()
};
$.ajax({
url: '#Url.Action("Subscribe", "Home")'
type: 'POST',
data: JSON.stringify(p),
dataType: "text json",
contentType: "application/json",
success: function (data) {
// get the result and do some magic with it
alert(data.foo);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});

help debugging an ajax problem

Anyone have any idea why this isn't working?
$(function(){
console.log('ready');
$.ajax({
dataType : 'jsonp',
jsonp : 'js',
url : 'http://monitor.302br.net/MonitorScoreServlet',
beforeSend : function(jqXHR, settings) {
console.info('in beforeSend');
console.log(jqXHR, settings);
},
error : function(jqXHR, textStatus, errorThrown) {
console.info('in error');
console.log(jqXHR, textStatus, errorThrown);
},
complete : function(jqXHR, textStatus) {
console.info('in complete');
console.log(jqXHR, textStatus);
},
success: function(data, textStatus, jqXHR){
console.info('in success');
console.log(data, textStatus, jqXHR);
}
});
});
This was working till recently. The beforeSend handler never fires, but you can see the ajax call being made in firebug, and if you go to the url, it seems to return acceptably formatted results (the same results as before):
http://monitor.302br.net/MonitorScoreServlet?js=jsonp1298046640938
text/javascript:
(84.3);
If I comment out the url, the beforeSend fires, but of course, there's no url....
Any ideas?
AJAX requests are, by definition, restricted to your current domain. Therefore, you cannot request an external URL from your domain.
Ok, I feel dumb. Here's what I think happened: the server used to be set up to take the js param as a callback function. So a url like:
http://monitor.302br.net/MonitorScoreServlet?js=foo
would result in:
foo(84.1);
Whenever we looked in the browser, we were just looking at:
http://monitor.302br.net/MonitorScoreServlet?js
which resulted in:
(84.1);
I assumed jQuery was doing some magic with that to turn it into usable data, but now I think that jQuery was creating something like:
function jsonp1298047240882(data) {
// do something with data
}
So when we changed our back-end code not to create the callback function call, the whole thing stopped working. (It's still weird that the beforeSend handler never gets called, though.)

Why won't jQuery call my Ajax error handler?

I have the following jQuery Ajax call (There are no other global settings/handlers):
$.ajax( {
url: "http://www.blah.com/url/does/not/exist",
type: "get",
data: someData,
dataType: "json",
error: function (xhr, msg, ex)
{
alert("Failed: " + msg);
},
complete: function (xhr, msg)
{
alert("Done: " + msg);
}
I would expect my error handler to be called, but instead the complete event fires and the alert displays Done: success. In my Javascript console, I see the following message:
XMLHttpRequest cannot load http://www.blah.com/url/does/not/exist.
Origin null is not allowed by Access-Control-Allow-Origin.
Why won't my error handler get called?
What is the meaning of the Origin message logged to the console?
Thanks!
Looks like the only way is to receive the server response in my success method and store it in a global variable, which I'll check in the handler for complete (which always gets called). No response means the request failed.
It's a shoddy way of handling errors in this otherwise excellent libary.
Your error handler isn't called because the AJAX request doesn't even take place: the browser refuses to do that because of the same origin policy: the data you're requesting would come from a different site than the one serving your page.
You can try using the JSONP data type to work around the problem:
$.ajax({
url: "http://www.blah.com/url/does/not/exist",
type: "get",
data: someData,
dataType: "jsonp",
error: function(xhr, msg, ex) {
alert("Failed: " + msg);
},
complete: function(xhr, msg) {
alert("Done: " + msg);
}
});

jQuery .ajax call shows success when computer disconnects. How to induce ajax error state?

I have the following bog standard jQuery ajax request. I've been trying to induce an error state by disconnecting my computer from the network mid-request (the server takes 10 seconds to reply so this is simple).
When I disconnect alert('Success: '+ json); is called, with null for the response json. I would expect the error part to be called.
Anyone know why the disconnect is being treated as a success, and how instead to induce a fail?
$.ajax({
url : 'post.php',
data : { id : 123 },
type: 'POST',
dataType : 'json',
success : function(json) {
alert('Success: '+ json);
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert('Error: ' + errorThrown);
},
complete : function(xhr, status) {
}
});
I think there was/is a bug since the release of jQuery 1.4.
After upgrading from 1.3.2 I noticed that calling an abort on the XMLHttpRequest object triggered the success callback, not the error callback. After poking around the codebase, I noticed that they had replaced the typical abort method with a custom one. Could have something to do with that.
Here's a post about it:
http://forum.jquery.com/topic/after-aborting-an-ajax-call-success-event-is-still-being-fired
$.ajax({
url : 'post.php',
data : { id : 123 },
type: 'POST',
dataType : 'json',
success : function(json) {
if(json!=null){
alert('Success');
}else{
exceptionAjax(0,"no server data");
}
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
exceptionAjax(XMLHttpRequest.statusText,XMLHttpRequest.responseText);
},
complete : function(xhr, status) {
}
});
function exceptionAjax(responseStatus,responseText){
alert('Error');
}

Resources