I have a sort of ajax polling cycle - pull message, process message, wait, pull again ... - everything works fine until user disconnects from the internet (it can be even so simple user action as sleep/hibernating the PC). After that - at least in latest Chrome - POST fails (logicly) - but after reconnecting to the internet the poll cycle does not get started again (even when the session is still ON).
jQuery(function(){
// ba polling main
function pollingMain() {
$.ajax({
type: "POST",
url: ba_home_url+"/pollingscript.php",
data: {
"load": "something",
"data-one": 0,
"data-two": 0
},
dataType: "json",
timeout: 60000,
success: function(data) {
if( data.status == 'nodata' ){
setTimeout(pollingMain,10000);
} else{
if( data.status == 'okdata' ){
console.log('Ok data recived');
setTimeout(pollingMain,10000);
} else{
//server responded with something we dont know what is
setTimeout(pollingMain,10000);
}
}
},
error: function(request, status, err) {
if(status == "timeout") {
setTimeout(pollingMain,10000);
}
}
});
}
pollingMain();
});
That is my code. I guess I am missing something in the error callback - but what error status handling should I add there ?
You are checking for specific status "timeout". Add else statement for handling other statuses.
Related
I want to implement a retry logic in my javascript code. This is how I'm calling the API:
$.ajax({
url: api_url + 'report',
type: 'GET',
dataType: 'json',
async: false,
tryCount : 0,
retryLimit : 3,
headers: {
"Authorization": "Basic " + btoa(api_username + ":" + api_pass)
},
data: {start: start_date, end: end_date},
success: function(result) {
data = result.results;
console.log("success");
},
error : function(xhr, textStatus, errorThrown ) {
console.log("in error");
if (textStatus == 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) {
//try again
console.log("try count:");
console.log(this.tryCount);
$.ajax(this);
return;
}
return;
}
if (xhr.status == 500) {
console.log("still 500");
} else {
console.log("still !500");
}
}
});
So when there are issues with the server and it returns http 500 then still my control in the above JS file doesn't go into the "error:" block and this line: "console.log("in error");" doesnt get printed on the console.
How can I correctly implement a retry logic in my code in case my server returns 500 then it should keep on retrying for some x amount of times?
500 error generally means that something is wrong with backend server. So it doesn't get into error block of client JavaScript. I don't think there is anything you can do. But in general you can always ask backend developers to do better error handling and return apt error response if possible.
I have an ajax function which updates my database.. The function works perfectly well and after updating the the database I call the successAlert() function I have created.. however now I want to call the error function in case of error however on testing purposely to break code I still get the successAlert().
Ajax / Javascript:
var share = "test"
var custid = "test"
$.ajax({
url: "assets/ajax/customer-rec.php",
type: "POST",
data: {UpdateAccount: "yes",custid: custid,share: share},
success: function(result){
successAlert()
},
error: function(result){
errorAlert()
}
});
PHP to update Database
if (isset($_POST['UpdateAccount'])){
$custid = $_POST['custid'];
$share = $_POST['share'];
$query="UPDATE `users` SET `share_ord`='$share' WHERE id= $custid";
$stmt = mysql_query($query);
if($stmt === false){
return false
}
}
return false is not an error. If you want to send the error use headers like
header('X-PHP-Response-Code: 404', true, 404);
you can call the same errorAlert() function in success also so that
$.ajax({
url: "assets/ajax/customer-rec.php",
type: "POST",
data: {UpdateAccount: "yes",custid: custid,share: share},
success: function(result){
if(result === false){
errorAlert()
} else {
successAlert()
}
},
error: function(result){
errorAlert()
}
});
To get error you need to return the status code '404' from the php function which is serving your request.
The error callback is fired when the server returns a HTTP status code that indicates an error, as such you should send one, ex HTTP 500
if($stmt === false){
header('HTTP/1.1 500 Server error');
}
See here a list of HTTP status codes
.ajax() will call on success method because, once your request is processed successfully by the server then it reruns HTTP_OK to the client and if .ajax not received HTTP_OK, then it will call error. According to your code, it will call success, because url is exists and server will send HTTP_OK to the browser.
If you want to generate error: then give wrong url or disconnect internet or simply change
In PHP:
if($stmt === false){
//If you want really generate some http error.
header('X-PHP-Response-Code: 500', true, 500);
exit(0);
//or else continue as per code
// return false;
}
In your JS:
$.ajax({
url: "assets/ajax/customer-rec.php",
type: "POST",
data: {UpdateAccount: "yes",custid: custid,share: share},
success: function(result){
if(!result){
showErrorAlert()
} else {
showSuccessAlert()
}
},
error: function(result){
showErrorAlert()
}
});
I am writing codes where the code will do some polling for statistics to the server using AJAX. My web application is getting data from the server every 3 seconds once the server returned the data. It is working good but however, I want to apply clearTimeout(x) function to stop the execution and print something to user when any error occur like "timeout" or "error" triggered by error setting. I managed to search the similar case with me here and this also link. But for some reason my code does not do what I want. Here is what I have so far
var timeoutid = 0;
var myfunc = function() {
$.ajax({
type: "POST",
url: "pull.php",
error: function(xhr, status, error){
if( status==="timeout" || status==="error") {
alert("Timeout or unable to receive statistics!");
clearTimeout(timeoutid);
}
},
success: function(msg){
$('#res').val(msg);
//timeoutid = setTimeout(poll, 3000);
},
complete: function(){
timeoutid = setTimeout(myfunc, 3000);
},
timeout: 5000
});
}
myfunc();
The result of the above when I disable my Internet adapter is it keeps looping and alert me the error without stopping the execution. I don't really know how or where do I put my clearTimeout due to localized variable issue based on what I have read. Not really a master in jQuery in detailed though. Appreciate your kind respond and thank you in advance.
It is because you are again creating a new timer in the complete callback which will get executed in the case of error also
var myfunc = function () {
$.ajax({
type: "POST",
url: "pull.php",
error: function (xhr, status, error) {
if (status === "timeout" || status === "error") {
alert("Timeout or unable to receive statistics!");
}
},
success: function (msg) {
$('#res').val(msg);
},
complete: function (jqXHR, status) {
if (status !== "timeout" && status !== "error") {
setTimeout(myfunc, 3000);
}
},
timeout: 5000
});
}
myfunc();
This is a very small application for a prototype/experiment. A device is going into sleep every so often to save battery life and a user will access a local webpage and press a button to change something with the device--this sends a POST to the device using the javascript code below.
Since the device can be sleeping when the user presses a button it will miss the POST. I know this is bad practice but I basically need the webpage to keep POST-ing (don't even know if I'm using the terminology correctly) or sending data until it receives the response. I tried a while loop but it only sent it once, maybe I put it in the wrong place.
function execPOST(url, postData, callback) {
var postRequest = newAjaxRequest();
postRequest.onreadystatechange = function() {
if (postRequest.readyState == 4) {
if (postRequest.error) {
callback(1, "Request had an error.");
alert('postRequest Error');
} else {
var status;
try {
status = postRequest.status;
} catch (err) {
callback(1, "Failed to get HTTP status from server.");
return;
}
if (status == 200 || status == 0) {
callback(0, postRequest.responseText);
} else {
callback(1, "POST: Unexpected HTTP Status: "
+ postRequest.status);
alert('POST: Unexpected HTTP Status: '
+ postRequest.status);
}
}
}
}
if (postRequest.overrideMimeType){
postRequest.overrideMimeType("text/xml");
}
postRequest.open("POST", url, false);
//I tried adding this while loop hoping it would keep sending but it only sent once
while (postRequest.readystate != 4)
{
setTimeout('',2000);
postRequest.send(postData);
}
return postRequest;
}
I suggest looking at socket.io to "ping" the device in a loop until it wakes up, THEN send the POST request.
have you considered to use jquery?
function ping () {
$.ajax (
<url>
, {
error: function ( jqXHR, textStatus, errorThrown ) {
}
, timeout: 5000 // in ms
, type: 'POST'
}
}).done(function ( data, textStatus, jqxhr ) {
// whatever
}).fail(function ( jqxhr, textStatus, data ) {
// note that the order of arguments is different from that of the success handler ('done') !
if (textStatus === 'timeout') {
ping();
}
else {
// ... more error handling
}
});
for more info, consult the docs.
I want to display data on a webpage as it comes, let's say I have a tracert on a server and it may take longish time, but I want to show the data as it comes.
If I make it like this:
$.ajax({
url: '/cgi-bin/trace.cgi',
dataType: 'text',
async: true,
cache: false,
success: function (response) {
$('#traceOut').append(response);
}
});
it will only be called when we are done with the cgi request.
I could do it directly with XMLHttpRequest, onreadystatechange and xmlhttp.readyState==3
This works ok in Firefox but in Chrome it only dumps data as it reaches 2k.
How do I do this in jQuery?
It is possible, with polling. The tricky part will be coordinating the process for multiple users on the server side. I'll explain the workflow below.
The Method
/**
* Polls a URL until server indicates task is complete,
* then sends a final request for those results.
*
* Requires jQuery 1.4+.
*/
function poll(params) {
// offer default params
params = $.extend({
error: function(xhr, status, err) {
console.log('Network error: ' + status + ', ' + err);
},
progress: function(prog) {
console.log(prog);
},
timeoutMillis: 600000, // 10 minutes
intervalMillis: 3000 // 3 seconds
}, params);
// kickoff
_poll(params);
function _poll(params) {
$.ajax({
url: params.url,
type: 'GET',
dataType: 'json',
timeout: params.timeoutMillis,
data: 'action=poll',
success: (function(response, status, xhr) {
if ('progress' in response) {
params.progress('Progress: ' + response.progress);
}
if ('status' in response) {
if (response.status == 'pending') {
// slight delay, then poll again
// (non-recursive!)
setTimeout((function() {
_poll(params);
}), params.intervalMillis);
}
else if (response.status == 'cancelled') {
params.progress("Task was cancelled");
}
else {
params.progress("Task complete");
// done polling; get the results
$.ajax({
url: params.url,
type: 'GET',
timeout: params.timeoutMillis,
data: 'action=results',
success: params.success,
error: params.error
});
}
}
}),
error: params.error
});
}
}
Example usage
poll({
url: '/cgi-bin/trace.cgi',
progress: function(prog) {
$('body #progress').text(prog);
},
success: function(response, status, xhr) {
$('body').html(response);
}
});
Workflow
This method will send a request to the server with parameter "action" set to "poll". The CGI script should launch its background task, persist some state in the user session, and respond with JSON-formatted strings:
{"status": "pending", "progress": "0%"}
The browser will repeatedly issue these "action=poll" requests until the response indicates completion. The CGI script must keep track of the task's progress and respond to the browser accordingly. This will involve session handling and concurrency:
{"status": "pending", "progress": "25%"}
{"status": "pending", "progress": "50%"}
{"status": "pending", "progress": "75%"}
{"status": "complete"}
The browser will then issue a "action=results" request to receive the background task's final payload. In this example, it's just HTML:
"<p>The answer is: 42</p>"