Reputation: 20269
What happens if I send some ajax request, and immediately change the page (say follow some link) before the request returns? I mean I suppose the XHR object sends a request to the website, but it is removed (since the page is changed) before the response is retrieved, so where should the response be sent to?
I am asking this question because I am having a strange problem with my website. I have a page that loads posts from the data store via an Ajax request. If before the load is complete I click on a link, I get the onerror of jQuery.ajax called! Not sure why that happens.
EDIT: This is my call to ajax. In the normal case, the success callback gets called. But when I click on a link, the error callback gets called! I am thinking about something, could it be because the data should be formatted as JSON, but the request is cut in the middle, so the data is considered invalid causing jQuery to call the error callback?! But then why the requests get cut in the middle?
$.ajax({
type: (args.rel == "async" || args.rel == "dialog") ? "GET" : "POST",
url: href,
dataType: "json",
data: args.data ? args.data:{}, // send {} to ensure Content-Length header
success: function(data){
if (context) context.removeClass("ajax_wait");
if (args.hideonwait) $(args.hideonwait).show();
if (args.showonwait) $(args.showonwait).hide();
if (spinner) remove_spinner(context, spinner);
handle_response(args, context, target, data);
},
error: function(xhr, status, errorThrown){
if (context) context.removeClass("ajax_wait");
if (args.hideonwait) $(args.hideonwait).show();
if (args.showonwait) $(args.showonwait).hide();
if (spinner) remove_spinner(context, spinner);
ajax_error(args, context,
status + "-" + xhr.status,
errorThrown ? errorThrown : xhr.responseText);
}
});
Upvotes: 13
Views: 7303
Reputation: 57
I had to deal with the same issue few days ago .. seems like its not that complicated to deal with.. We should able to distinguish the weather its a ajax error of some sort or user abort the request.. of course we don't get specific event from xhr object .. that's why ajax error comes with an exception ...combination of both xhr object and exception value we can solve this.
var message = '';
$('whatever').ajaxError(function(e, xhr, settings, exception) {
// logic
if (!xhr.status){
if (exception=='abort'){
message = 'User aborted AJAX request !';
}
}
}
Upvotes: 0
Reputation: 47804
The trick is to check the response headers in the XMLHttpRequest object. If there are no response headers (null or empty string, depending on the browser), the server did not respond yet. That means the user aborted.
$.ajax({
url: "url-to-go-here",
success: function() {
},
error: function(xhr, textStatus, errorThrown) {
if(!isUserAborted(xhr)) {
console.log("Ajax Error")
}
}
});
function isUserAborted(xhr) {
return !xhr.getAllResponseHeaders();
}
Upvotes: 11
Reputation: 314
The solution to this problem is simple, all you need to do is if the request is currently running and if the user clicks any other link, then you need to alert the user that the request is under process please wait
To achieve this you need to maintain a semaphore, set that semaphore before firing any request and reset it on completion of that request. On click of every link(which changes the page) call a method which checks the semaphore and if it is set then the method gives the above alert to the user. This way, until the request completes, the user wont be able to change the page, and your problem of request being aborted would be solved
Hope this answers the question.
Upvotes: 1
Reputation: 618
The behavior seems to be when the user leaves a page, any outstanding ajax requests complete with 0 as their status. jQuery interprets this as an error, which is why it calls the error handler. In your error handler, you can call the same function that your success handler calls if xhr.status == 0, otherwise execute the desired error behavior.
Upvotes: 3
Reputation: 10243
You would be out of luck. You would have no callback to come back to. Ajax response would be lost. In this case I would put a blocker on the page. It's pretty common, in order to prevent another click. Blocker nothing more than big mask which "lays over" the entire browser. It could also have a wait icon.
Upvotes: 0