In my web application, I am trying to handle time out situations when calling a REST API. Here is my code which calls the API using jQuery ajax.
$.ajax({
type: "POST",
url: endpoint,
data: payload,
dataType: dataType,
timeout: 0,
success: successHandler,
error: failureHandler
});
The success and failure handlers are shown below.
function successHandler(data) {
//Got the data
}
function failureHandler(xhr, textStatus, thrownError) {
if(xhr.status==404) {
console.log('Page not found');
} else if(xhr.status==408) {
console.log('request timed out at server. You may want to retry') ;
}
}
If the timeout happens at the server, it is giving status 408. But sometimes, due network connectivity problems, the client (browser) itself is getting timed out because it is not able to connect to the service in specified time. I guess this is the browser behavior. What will be xhr.status and textStatus if the request gets timed out by the browser? How to handle this scenario?
[Edit] I found some explanation in Set timeout for ajax (jQuery). This explains how we can set timeout in the code. But my question is that I don't want to set timeout like this. Check the code in ajax request, I set timeout: 0 which means, there is no timeout and I am going to wait till I get the response from the server. Meanwhile, the browser may kill this request because of it's global timeout setting. I am looking for a solution which can handle this.
This looks like it is a very similar question to this post. Good luck!
How to detect timeout on an AJAX (XmlHttpRequest) call in the browser?
Related
I have ajax call where I process large data and then reload the page in ajax success. Ajax call is
$.ajax({
type:'POST',
cache:false,
async:false,
url: 'URL',
data: "",
timeout:0,
beforeSend:function(msgg){
$('#loading').show();
},
success: function(data){
if(data == "success")
{
setTimeout(function(){
$('#loading').hide();
window.location.reload();
},5000);
}
}
});
but it gets 504 GATEWAY_TIMEOUT and ajax call never comes in success. I need manual refresh.
504 GATEWAY_TIMEOUT errors normally occur when your API Gateway URL is not responsive. It could be some kind of internal Gateway error.
Here are some steps to troubleshoot:
Use a proxy like Postman to make the same exact request and see what the response is
Make sure your path is correct
If there are other requests that you make to the same gateway URL, maybe a GET request, try making those calls manually or using your code, to make sure the gateway is working fine
If you have access to the Gateway, restart it (this is possible if you have Microservices architecture, and Dockerisation etc)
The recommendation is to make more short calls to check status / retrieve data.
Here is the alternative if the above is not possible:
Notice: This solution is not recommended for production use or high traffic scenarios, make sure this action is performed on an isolated server.
If using Apache Web Server 2.4, the TimeOut directive is by default set to 60 seconds.
For more details see this article.
The web server will only keep the connection open for 60 seconds regardless the max_execution_time
While the max_execution_time in php.ini sets the execution time of php, the Apache TimeOut directive sets the maximum connection time.
Example:
if php max_execution_time is 120 sec, but TimeOut is 30 sec - you will get a 504 error
if php max_execution_time is 120 sec, but TimeOut is 300 sec - your script will execute for max 120 seconds, but your connection can stay alive for 300 seconds
If you didn't set any response code from php, PHP returns 200 if everything is OK, 500 if error occured.
When you get an unexpected HTTP Response code it's good to keep an eye on the web server too.
I think browser can not hold for long ajax call so I used ajax recall and processed data in parts. It solved problem.
Found working solution posted by #david-hoerster
As he said, If your error event handler takes the three arguments (XMLHttpRequest, textstatus, and message) when a timeout happens, the status arg will be 'timeout'
$.ajax({
url: "/ajax_json_echo/",
type: "GET",
dataType: "json",
timeout: 1000,
success: function(response) { alert(response); },
error: function(xmlhttprequest, textstatus, message) {
if(textstatus==="timeout") {
alert("got timeout");
} else {
alert(textstatus);
}
}
});
With jsFiddle, you can test ajax calls -- it will wait 2 seconds before responding. I put the timeout set at 1 second, so it should error out and pass back a textstatus of 'timeout' to the error handler.
I have a web app, requesting and sending data via AJAX, and as a response, my server-side sends HTTP status codes, depending on the situation. so for example if a user tries to login while he's logged I probably return a 400 HTTP status code. And eventually i handle it with an alert, etc.
But handling these HTTP Status codes gets too heavy, since I'm making heavy use of AJAX. that means I'll be handling HTTP status code repeatedly with every AJAX request, which will result in duplicated code, and that's a bad practice.
So, what I'm looking for is a way to handle all these errors in one place, so I just handle all 400, 401, etc with the same code.
What i'm currently doing:
Handling the errors manually for each AJAX call. By using the statusCode in$.ajax().
statusCode: {
500: function(data) {
alert('Some friendly error message goes here.');
}
It seems like an overkill for me, as my web app develops, and as I create more ajax calls. I'll be repeating this piece of code again and again.
Currently, the only idea I have in mind is creating a function that will work on top of AJAX, something like:
function doAjax(type,url, data, moreVars) {
//this function is just a SIMPLE example, could be more complex and flexible.
$.ajax({
type: type,
url: url,
data: data,
moreOptions:moreVars,
//now handling all status code.
statusCode: {
//handle all HTTP errors from one place.
}
});
}
doAjax("POST", 'mydomain.com/login.php', dataObj);
You can use $.ajaxSetup() to register global error state handlers.
Description: Set default values for future Ajax requests.
Example:
$.ajaxSetup({
statusCode: {
500: function(data) {
alert('Some friendly error message goes here.');
}
}
});
I have a form that I have been submitting to Salesforce with standard form submit action. By default, you can tell Salesforce to redirect you to a given URL after the POST has completed.
I no longer wish to be redirected since I have other activities on the form page. No problem, my page is already using jQuery so I can use the handy $.ajax utility like this:
$('#wrapper').on('click', '#formsubmit', function(e) {
e.preventDefault();
var formData = $('#subForm').serialize();
$.ajax({
type: "POST",
url: "https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8",
data: formData,
success: function() {
console.log('success!'); // or not!
},
error:function (xhr, ajaxOptions, thrownError){
console.log(xhr.status); // 0
console.log(thrownError); // empty
}
});
});
In my misguided brain, I imagined that Salesforce would return my good ol' redirect, which would count as a "success" that I can just discard/ignore. Misguided indeed!
I can see a 200 OK result (which usually means "success") but the success callback isn't tripped.
The lead is added to the Salesforce database
Inspecting the content of what's returned shows zero; there is no content in the response.
The error callback IS being tripped (despite the 200 OK) but maybe due to intentionally not redirecting it is seen as a "resource not available"? (therefore my status code is 0, and there is no content in the thrownError?).
Any advice on identifying this as a successful POST so that I can trigger additional actions in a callback? I don't want to TOTALLY ignore the response, or I could end up in a scenario in which I'm acting on a failed POST as if it was successful. I need to capture the success somehow.
It occurred to me that it could be a cross-site scripting issue as well, but since the application doesn't exchange data in JSONP, I'm not sure how to get around that (and I'm not sure how to identify it in the first place).
Few things here:
1) The redirect response being sent by salesforce's API is most likely being interpreted as an error code.
2) The response code of the subsequent page (after the redirect) is 200 OK, from the sound of it.
3) It is not possible to do a POST request using JSONP. This is a limitation of JSONP; which is not actually an AJAX request, but an HTTP GET request wrapped inside of a dynamically generated script tag. Also, JSONP only works if the request yields an HTTP response of 200 OK.
I would recommend using your own server-side intermediary to handle your AJAX POST request. This will act as a proxy between your front-end app and salesforce's API. This will also allow you to better control the response being sent to your app.
var formData = $('#subForm').serialize();
var response = $.ajax({
type: "POST",
url: "https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8",
data: formData,
success: function() {
console.log('success!'); // or not!
},
error:function (xhr, ajaxOptions, thrownError){
console.log(xhr.status); // 0
console.log(thrownError); // empty
}
}).responseText;
where var response will contain the return value from your ajax call
I am using jQuery Mobile to create a webapp to look at and update a CRM type system.
The mobile app sends update using jQuery.get and jQuery.post and they work fine when network connection is available.
How should I code or what can I use to queue the jQuery.get and jQuery.post calls when the network connection is not available so they are sent when it becomes available again.
Edit: ah poo, i just noticed you said 'jQuery Mobile', I initially read that as jquery for mobile lol. Ummm, this'll probably only work as long as jQM supports ajax the same as normal jquery
I had an idea with a secondary ajax request, but you shouldn't need that. Just set up your AJAX like this, and give it a timeout. If it takes > 4 (should be enough for a broadband connection, but some phones may need ~10-15) seconds for the server to respond, it'll just try the ajax request again up to retryLimit, which can be set, then changed later as well after the 50 times is up (i.e. should it send when the program is idle and has no data perhaps?). When it connects, it'll go to the success function, which will then send the data to the server.
So it'd be like:
$.ajax({
type: 'GET',
timeout: 4000,
tryCount : 0,
retryLimit: 50,
success:function(data) {
sendSavedData();
}
error: function(xhr, textStatus, errorThrown) {
if(textStatus == 'timeout') {
this.tryCount++;
if(this.tryCount <= this.retryLimit) {
$.ajax(this);
return;
}
var check = confirm('We have tried ' + this.retryLimit + ' times to do this and the server has not responded. Do you want to try again?');
if(check) {
this.timeout = 200000;
$.ajax(this);
return;
} else {
return;
}
}
}
});
I am doing AJAX with JQuery but every time the "onSuccess" event must be executed after another AJAX request disconnected.
Here is the code:
d.ajax({
url: f.options.url.offline,
dataType: "jsonp",
jsonp: "callback",
cache: false,
data: {
status: "offline",
ticket: f.connection.options.ticket
},
success: function(g) {
f._offlineSuccess()
},
error: function() {
f._offlineError()
}
})
All my AJAX requests are JSONP, and when the above code is triggered, there is another AJAX connection (long polling request, last about 10 senconds) already established in the mean time. So the "f._offlineSuccess" function is always executed after another AJAX connection disconnected.
I can not see any relationship between the two AJAX requests, and I don't know why the "onSuccess" function must be executed after another AJAX connection stopped.
Any help is appreciated~
================================
updated:
I just found out if I have two JSONP connection at the same time, the "onSuccess/onFailure" function will be blocked. I don't know if some one encountered the same problem before?
Ajax requests are asynchronous. so a new request is not going for the previous one to finish. If you want that behaviour use async parameter to false, or use the complete() function to call for another request. This will fire only when the first request is finished.
UPDATE
For JsonP use jQuery.getJSON() and do the second request on callback if the call was succesfull.
function (data, textStatus) {
// data will be a jsonObj
// textStatus will be one of the following values:
// "timeout","error","notmodified","success","parsererror"
this; // the options for this ajax request
}
If you use firebug - net tab, you will be able to see the full url of the two jsonp requests. You should be able to see the callback function names on the end of the url. Are these different or the same? I can only assume they are the same.