ajax call aborted auto - javascript

Im having a very weird issue.
I have a normal ajax call that upload the avatar you choose from your pc up to the server..
this works sometimes, sometimes i can see in firebug under the Net that after some time loading, it gets "Aborted" and marked in red.
i even have a ajaxstart ajaxend loader icon and the icon keeps showing even when it gets aborted.
Why is this happening, and how can i prevent it from aborting? And maybe how can i make a "try again" if it got aborted?..why is it even aborted :S
Ive noticed it happening on bigger demension/size files? And on the file it request(fileupload.php) i do have a checker there, to callback an error if its bigger. But i think it does not even get to the file before it "lags" and stops..
Update confirmed: this occurs when i try to ajax send file with bigger size..

How are you sending files through Ajax? Ajax does not support sending files.
If it is a connection timeout in jQuery console it will show in red color and the failure handler of the ajax request will be called.
You can handle any conditions you want there. To remove timeout issue you can add a attribute timeout to your ajax request. I think the default value is 30 seconds
$.ajax({
url : "",
data : {},
success : function(data, textStatus, XMLHttpRequest){
},
error: function(XMLHttpRequest, textStatus, errorThrown){
if(textStatus == "timeout"){
alert("timeout")
}
},
timeout : 600000
});
Since you are using ajaxfileupload try this
$.ajaxFileUpload({
.....,
timeout: 60000,
error: function (data, status, e)
{
if(status == "timeout"){
alert("timeout")
}else{
alert(status)
}
}
})
And make sure that you does not have any max file upload size set in your server.

It probably got aborted because the request timed out on the client side. Increase the timeout in jquery.

Related

Ajax file upload returns status code 0 ready state 0 (only sometimes)

I have looked at the following thread
jQuery Ajax - Status Code 0?
However I could not find a definitive answer and I am having serious trouble trying to find the source of my issue so I am posting here in the hopes that someone can point me in the right direction.
In my code I am performing an Angular HTTP post which just sends basic JSON data, then within the on success callback I am using AJAX to upload files to the same server. (I know I should not be using jQuery and Angular however I can't change this for the moment)
It looks something like this
var deferred = $q.defer()
// first post
$http.post(url,payload,{params: params, headers: headers)
.then(function(response) {
uploadFiles(response,deferred);
// I am also sending google analytics events here
}, function(error) {
// do error stuff
}
return deferred.promise;
// upload files function
function uploadFiles(response,deferred){
$ajax({
type: 'POST',
processData: false,
contentType: false,
data: data // this new FormData() with files appended to it,
url: 'the-endpoint-for-the-upload',
dataType: 'json',
success: function(data) {
// do success stuff here
deferred.resolve(data);
},
error: function(jqXHR, textStatus, errorThrown) {
var message = {};
if (jqXHR.status === 0) {
message.jqXHRStatusIsZero = "true";
}
if (jqXHR.readyState === 0) {
message.jqXHRReadyStateIsZero = "true";
}
if (jqXHR.status === '') {
message.jqXHRStatusIsEmptyString = "true";
}
if (jqXHR.status) {
message.jqXHRStatus = jqXHR.status;
}
if (jqXHR.readyState) {
message.jqXHRReadyState = jqXHR.readyState;
}
if (jqXHR.responseText) {
message.jqXHR = jqXHR.responseText;
}
if (textStatus) {
message.textStatus = textStatus;
}
if (errorThrown) {
message.errorThrown = errorThrown;
}
message.error = 'HTTP file upload failed';
logError(message);
deferred.resolve(message);
}
}
})
}
Not my exact code but almost the exact same.
The issue is that is works almost all of the time, but maybe three or four in every few hundred will fail. By fail I mean the error handler function is called on the file upload function and the files are not uploaded.
I get jqXHRStatus 0 and jqXHRReadyState 0 when this occurs.
The only way I am able to replicate the issue is by hitting the refresh on the browser when the request is being processed, however users have advised they are not doing this (although have to 100% confirm this)
Is there perhaps a serious flaw in my code which I am not seeing? Maybe passing deferred variable around isn't good practice? Or another way the ajax request is being cancelled that I am not considering? Could sending google analytics events at the same time be interfering?
Any advice would be great and please let me know if you would like more information on the issue.
This means, the request has been canceled.
There could be many different reasons for that, but be aware: this could be also due to a browser bug or issue - so i believe (IMHO) there is no way to prevent this kind of issues.
Think for example, you get a 503 (Service Unavailable) response. What you would do in such a case? This is also a sporadic and not predictable issue. Just live with that, and try to repost your data.
Without reinventing the wheel, I suggest you to implement:
Retrying ajax calls using the deferred api
My guess is that your code is executing before it actually gets back from the call. I.e. the call goes back and nothing was returned and it gives a 0 error. This would make sense as the error is variable. Most of the time it would return fine because the backend executed fast enough but sometimes it wouldn't because it took especially long or something else happened etc. Javascript doesn't ever REALLY stop execution. It says it does but especially passing between angular and jquery with multiple ajax requests it wouldn't be surprising if it was executing the second ajax call before it actually completed your angular post. That's why a refresh would replicate the error because it's would clear your variables.
Some things you can do to test this:
On the backend make a timer that goes for a few seconds before it returns anything. This will probably make your code fail more consistently.
Set breakpoints and see when they are being hit and the values they contain in the javascript.
Good luck!

jQuery post and get not returning anything, despite the network request is being sent succesfully

I have the following javascript function:
function test() {
jQuery.post("http://www.example.com/test.php", {})
.done(function(data) {
alert(data);
})
.fail( function(xhr, textStatus, errorThrown) {
console.log(xhr);
console.log(textStatus);
console.log(errorThrown);
});
}
And the test.php file reads like this:
<? echo "TEST"; ?>
When I call this function either by clicking on something on my page, either by typing it to the console, the alert is not firing, instead the fail part of the jQuery.post is being fired, where I get the following values:
xhr -> object
textStatus -> "error"
errorThrown -> ""
I've checked firefox debugers network, where I see that the request is being sent to the desired url, and the little circle at the left side gets green, which means that I get some kind of response from the server, but the transfered column is a single "-" line, and the received column is 0 bytes. If I call the page "http://www.example.com/test.php" from a browser, it works correctly.
What could be the problem, or how could I proceed on debuging this error?
Figured out the problem, see my own answer below, if anyone experiences the same error:|
Figured out the problem. I was accessing my site as example.com from the browser, and not as www.example.com where I send my ajax request. Ajax handled the request as cross-domain and that's why I didn't get an answer... dumb me...

Ajax Timeout Not Working and Not Showing "Timeout" Status

I am trying to do a connection check for a form before it is submitted, when the button is clicked on. The idea is to look through a Timeout request "Timeout()..." which is not implemented yet in this code, and keep iterating through the Ajax until a connection is found, as sometimes out in the field the connection can drop. When a connection is found it will alert the user and will submit successfully if there was a dropped connection after hitting submit. Here is what I have so far:
function upload_prepformDiff() {
$.ajax({
type: 'POST',
url: './php/upload_prepform.php',
timeout: 2000, //2 seconds, for testing purposes
data: prepform,
async: false,//Omitted now as of this post
dataType: 'text',
success: function() {
alert("Your Prep form has been submitted.");
window.top.location.replace('./');
},
error: function (xhr, status, error) {
if(status == "timeout") {
alert("Internet connection has been lost! Please wait until you are notified and do not continue.");
} else {
alert(status + " " + error);
}
}
});
};
The issue is that even with a low timeout value, I do not get a "timeout" status message I get "error." So it never throws the timeout error I need and for error I get: Error: NETWORK_ERR: XMLHttpRequest Exception 101
So the ajax does notice there is no connection, but that is what the errorThrown shows, while the textStatus is "error" for (xhr, status, error) respectively. So what I TRIED doing was do a little improvising and do some type of error.indexOf() deal with the error string thrown in the Ajax, but that didn't work nor did error.contains("NETWORK_ERR") or any type of Regex command. Any ideas for improving this or why I am not getting a timeout? Thanks!
Guess this might be a bit late for you, but nevertheless...
If you have specified
async as 'false'
, the timeout property will be ignored.
As for handling the errors, you can visit an earlier SO question:
status of ajax or post request
Hope this helps! :)

Chrome not handling jquery ajax query

I have the following query in jquery. It is reading the "publish" address of an Nginx subscribe/publish pair set up using Nginx's long polling module.
function requestNextBroadcast() {
// never stops - every reply triggers next.
// and silent errors restart via long timeout.
getxhr = $.ajax({
url: "/activity",
// dataType: 'json',
data: "id="+channel,
timeout: 46000, // must be longer than max heartbeat to only trigger after silent error.
error: function(jqXHR, textStatus, errorThrown) {
alert("Background failed "+textStatus); // should never happen
getxhr.abort();
requestNextBroadcast(); // try again
},
success: function(reply, textStatus, jqXHR) {
handleRequest(reply); // this is the normal result.
requestNextBroadcast();
}
});
}
The code is part of a chat room. Every message sent is replied to with a null rply (with 200/OK) reply, but the data is published. This is the code to read the subscribe address as the data comes back.
Using a timeout all people in the chatroom are sending a simple message every 30 to 40 seconds, even if they don't type anything, so there is pleanty of data for this code to read - at least 2 and possibly more messages per 40 seconds.
The code is 100% rock solid in EI and Firefox. But one read in about 5 fails in Chrome.
When Chrome fails it is with the 46 seconds timeout.
The log shows one /activity network request outstanding at any one time.
I've been crawling over this code for 3 days now, trying various idea. And every time IE and Firefox work fine and Chrome fails.
One suggestion I have seen is to make the call syncronous - but that is clearly impossible because it would lock up te user interface for too long.
Edit - I have a partial solution: The code is now this
function requestNextBroadcast() {
// never stops - every reply triggers next.
// and silent errors restart via long timeout.
getxhr = jQuery.ajax({
url: "/activity",
// dataType: 'json',
data: "id="+channel,
timeout: <?php echo $delay; ?>,
error: function(jqXHR, textStatus, errorThrown) {
window.status="GET error "+textStatus;
setTimeout(requestNextBroadcast,20); // try again
},
success: function(reply, textStatus, jqXHR) {
handleRequest(reply); // this is the normal result.
setTimeout(requestNextBroadcast,20);
}
});
}
Result is sometimes the reply is delayed until the $delay (15000) happens, Then the queued messages arrive too quicly to follow. I have been unable to make it drop messages (only tested with netwrok optomisation off) with this new arrangement.
I very much doubt that delays are dur to networking problems - all machines are VMs within my one real machine, and there are no other users of my local LAN.
Edit 2 (Friday 2:30 BST) - Changed the code to use promises - and the POST of actions started to show the same symptoms, but the receive side started to work fine! (????!!!???).
This is the POST routine - it is handling a sequence of requests, to ensure only one at a time is outstanding.
function issuePostNow() {
// reset heartbeat to dropout to send setTyping(false) in 30 to 40 seconds.
clearTimeout(dropoutat);
dropoutat = setTimeout(function() {sendTyping(false);},
30000 + 10000*Math.random());
// and do send
var url = "handlechat.php?";
if (postQueue.length > 0) {
postData = postQueue[0];
var postxhr = jQuery.ajax({
type: 'POST',
url: url,
data: postData,
timeout: 5000
})
postxhr.done(function(txt){
postQueue.shift(); // remove this task
if ((txt != null) && (txt.length > 0)) {
alert("Error: unexpected post reply of: "+txt)
}
issuePostNow();
});
postxhr.fail(function(){
alert(window.status="POST error "+postxhr.statusText);
issuePostNow();
});
}
}
About one action in 8 the call to handlechat.php will timeout and the alert appears. Once the alert has been OKed, all queued up messages arrive.
And I also noticed that the handlechat call was stalled before it wrote the message that others would see. I'm wondering if it could be some strange handling of session data by php. I know it carefully queues up calls so that session data is not corrupted, so I have been careful to use different browsers or different machines. There are only 2 php worker threads however php is NOT used in the handling of /activity or in the serving of static content.
I have also thought it might be a shortage of nginx workers or php processors, so I have raised those. It is now more difficult to get things to fail - but still possible. My guess is the /activity call now fails one in 30 times, and does not drop messages at all.
And thanks guys for your input.
Summary of findings.
1) It is a bug in Chrome that has been in the code for a while.
2) With luck the bug can be made to appear as a POST that is not sent, and, when it times out it leaves Chrome in such a state that a repeat POST will succeed.
3) The variable used to store the return from $.ajax() can be local or global. The new (promises) and the old format calls both trigger the bug.
4) I have not found a work around or way to avoid the bug.
Ian
I had a very similar issue with Chrome. I am making an Ajax call in order to get the time from a server every second. Obviously the Ajax call must be asynchronous because it will freeze up the interface on a timeout if it's not. But once one of the Ajax calls is a failure, each subsequent one is as well. I first tried setting a timeout to be 100ms and that worked well in IE and FF, but not in Chrome. My best solution was setting the type to POST and that solved the bug with chrome for me:
setInterval(function(){
$.ajax({
url: 'getTime.php',
type: 'POST',
async: true,
timeout: 100,
success: function() { console.log("success"); },
error: function() { console.log("error"); }
});
}, 1000);
Update:
I believe the actual underlying problem here is Chrome's way of caching. It seems that when one request fails, that failure is cached, and therefore subsequent requests are never made because Chrome will get the cached failure before initiating subsequent requests. This can be seen if you go to Chrome's developer tools and go to the Network tab and examine each request being made. Before a failure, ajax requests to getTime.php are made every second, but after 1 failure, subsequent requests are never initiated. Therefore, the following solution worked for me:
setInterval(function(){
$.ajax({
url: 'getTime.php',
cache: false,
async: true,
timeout: 100,
success: function() { console.log("success"); },
error: function() { console.log("error"); }
});
}, 1000);
The change here, is I am disabling caching to this Ajax query, but in order to do so, the type option must be either GET or HEAD, that's why I removed 'type: 'POST'' (GET is default).
try moving your polling function into a webworker to prevent freezing up in chrome.
Otherwise you could try using athe ajax .done() of the jquery object. that one always works for me in chrome.
I feel like getxhr should be prefixed with "var". Don't you want a completely separate & new request each time rather than overwriting the old one in the middle of success/failure handling? Could explain why the behavior "improves" when you add the setTimeout. I could also be missing something ;)
Comments won't format code, so reposting as a 2nd answer:
I think Michael Dibbets is on to something with $.ajax.done -- the Deferred pattern pushes processing to the next turn of the event loop, which I think is the behavior that's needed here. see: http://www.bitstorm.org/weblog/2012-1/Deferred_and_promise_in_jQuery.html or http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/
I'd try something like:
function requestNextBroadcast() {
// never stops - every reply triggers next.
// and silent errors restart via long timeout.
getxhr = jQuery.ajax({
url: "/activity",
// dataType: 'json',
data: "id="+channel,
timeout: <?php echo $delay; ?>
});
getxhr.done(function(reply){
handleRequest(reply);
});
getxhr.fail(function(e){
window.status="GET error " + e;
});
getxhr.always(function(){
requestNextBroadcast();
});
Note: I'm having a hard time finding documentation on the callback arguments for Promise.done & Promise.fail :(
Perhaps it can be worked around by changing the push module settings (there are a few) - Could you please post these?
From the top of my head:
setting it to interval poll, would kinda uglily solve it
the concurrency settings might have some effect
message storage might be used to avoid missing data
I would also use something like Charles to see what exactly does happen on the network/application layers

How to detect Ajax call failure due to network disconnected

I am sending lots of data using jquery ajax method to web sever and client side respond only after receiving acknowledgment from server, now suppose network connection lost in MIDDLE of ajax call then how to detect this situation.
$.ajax({
url:'server.php',
data:'lots of data from 200KB to 5MB',
type:'post',
success: function(data)
{
alert('Success');
//some stuff on success
},
error: function(XMLHttpRequest, textStatus, errorThrown)
{
alert('Failure');
//some stuff on failure
}
});
This is my code and and it does not give error in middle of ajax call if get internet is disconnected.
NOTE : I cant use time out because data size is vary from 200kb to 5MB and server response time calculation is not feasible.
Try this:
First create a "ping" ajax call with setInterval every 5 seconds
function server_ping()
{
$.ajax({
url:"url to ping",
type: "POST"
});
}
var validateSession = setInterval(server_ping, 5000);
then arm your .ajaxError trap:
$(document).ajaxError(function( event, request, settings ) {
//When XHR Status code is 0 there is no connection with the server
if (request.status == 0){
alert("Communication with the server is lost!");
}
});
Remember Ajax calls are Asynchronous by default, so when the pings are going to the server and the request cannot reach the server the value on the XHR status is 0, and the .ajaxError will fire and you must catch the error and handle the way you want it.
Then you can send your data to the server, if the connection is lost when sending the data you get the error reported by the ping.
If your server was not very crowded, probably you could use a timer to start detecting the connection regularly when you start transferring the data (by using another ajax calling, for instance each 5 seconds). now you can use timeout.
Btw,
1)timeout doesn't always means network error. sometimes server's down also causes "timeout"
2)if the driver is down on client device, xhr.status = 0, and no timeout
I had a similar problem and solved it with a simpel try/catch and a re-try delay of (say) 2 seconds:
function myAjaxMethod()
{
try
{
$.ajax({ ... });
} catch (err)
{
console.log(err.message);
setTimeout(function(){myAjaxMethod(),2000});
}
}
I faced a similar situation like yours and fixed it by having a network check for every 5 seconds and if network is disconnected i would abort the ajax request manually which will end the ajax request.
Here i get the ajax XmlHttpRequest in the beforeSend event of the Jquery ajax call and use that object to abort the ajax request in case of network failure.
var interval = null;
var xhr = null;
$.ajax({
beforeSend: function(jqXHR, settings) {
xhr = jqXHR; // To get the ajax XmlHttpRequest
},
url:'server.php',
data:'lots of data from 200KB to 5MB',
type:'post',
success: function(data)
{
alert('Success');
//some stuff on success
},
error: function(XMLHttpRequest, textStatus, errorThrown)
{
alert('Failure');
//some stuff on failure
},
complete: function(data)
{
alert('Complete');
//To clear the interval on Complete
clearInterval(interval);
},
});
interval = setInterval(function() {
var isOnLine = navigator.onLine;
if (isOnLine) {
// online
} else {
xhr.abort();
}
}, 5000);
Try adding timeout: while constructing your $.ajax({}).
Also make sure to set cache: false, helpful sometimes.
Refer to Jquery's ajax() : http://api.jquery.com/jQuery.ajax/#toptions
You will get much more information there!
My thought s on your problem[updated]
#RiteshChandora , I understand your concern here. How ever I can suggest you to do 2 things.
As you have post data ranging from 200kb to 5mb, you might want to choose a maximum timeout. and trigger for the same. Yes, this might be problematic, but with the design you chosen, the only way to monitor the POST progress is to do this way. if not, see point 2.
I went through the flow, you are asking the user to copy the response Json from FB to your url. there are some problems here,
The json data has sensitive information about the user, and he is posting it on a url without SSL encryption.
Why should you prompt the user to post the acquired data on to your server? it should be easier if you user sever side scripts. Also you should never post huge data from the client to the server in occasions like these, where you could retrieve the same form the FBserver->your sevrer on the server side.
My suggested solution : after the user is authenticated , retrieve his friends list on the server side. do whatever you want on the server side, and display the result on the users screen.
This way all the burden will be taken by your server, also there is no need for the user to do any nasty json posting on your url.
Btw, your app idea is cool.
error: function(xhr, textStatus, thrownError)
{
alert(xhr.status);
alert(thrownError);
alert(textStatus);
}
Try them..
TextStatus (besides null) are "timeout", "error", "abort", and "parsererror".
When an HTTP error occurs, thrownError receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."
If Internet disconnects,the response wont be received and maximum it would be a timeout message..

Categories