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;
}
}
}
});
Related
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?
I have a web application that loads different content into the same div (.content) using either an ajax request or a .load() request.
A simplified version of the ajax request is:
$(document).on('click', '.button1', function() {
$.ajax({
type: "POST",
url: "/path/to/file/ajax.php",
data: {
'param1': 'xyz',
'param2': '123',
},
timeout: 10000,
dataType: "json",
success: function(data) {
if (data.status == 'Success') {
$('.content').html(data.result);
} else if (data.status == 'Error'){
console.log('Something went wrong')
}
},
error: function(x, status, error) {
if (status === "timeout") {
console.log('Request Timed Out');
}
},
});
});
on another button I have:
$(document).on('click', '.button2', function() {
$('.content').load('/path/to/file/getContent.php?ref=foo');
});
The problem is that if I click on button1, and then click on button 2 whilst the ajax request is still executing, nothing happens. (ie. getContent.php doesn't seem to return anything for anywhere between 15-30 seconds)
Clicking on button 2 returns the results instantly, but as soon as button1 is clicked and the ajax request is being processed, it seems to "stall" the entire web app until it's completed (or errors).
(I've also tried using the abort() method to cancel the ajax request, but the same problem persists, even when the abort is successful).
UPDATE
See solution/Answer below
Following on from the tip from #adeneo, I did some more research into session_start and ajax calls which led me to this article:
http://konrness.com/php5/how-to-prevent-blocking-php-requests/
The problem absolutely was to do with session_start locking the session file which causes back-end issues with multiple ajax requests. Following the advice in the article above, I made use of session_write_close() in my PHP and everything is working great.
If it helps anyone else, I actually changed my code from session_start() to:
if (session_status() == PHP_SESSION_NONE) {
session_start();
session_write_close();
}
This makes session variables readable, but no longer locks the session file causing ajax request delays. (It also checks to make sure session_start() hasn't already been called)
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.
In fact, I have a JavaScript application (jQuery) that is sending a request to a Java function which is supposed to send back data (success case) to my ajax function.
In the success case, I go on with my application; in error case, I stop my procedures and display the error message to the user.
But when the Java code takes more than 5 minutes to send a response to my Ajax call, this one (ajax code) doesn't (work / respond / go on /) get any response anymore ...
I tried setting up a timeout limit to 600000 ms (so 10 minutes) but I still get the same problem (and ain't got any error messages or output, which could have been helping me).
So if anyone's got an idea on the source of this problem, I'd be grateful.
Here is some piece of code if it may make it clearer :
JSP
$(document).ready(function() {
/* performing some layout changes */
//
preValidationDisplay();
}
function preValidationDisplay() {
/* performing some layout changes */
setTimeout("getValidationResult()", 500);
}
function checkReadLogFile() {
$.ajax({
url: logFileUrl,
cache: false,
success: function(result)
{
$("#progressBarToResize").width(
'' + parseFloat(result.trim()) + '%' );
}
});
}
function getValidationResult()
{
var timer = setInterval("checkReadLogFile()", 1000);
$.ajax({
url: '<s:url value="doValidation"/>',
type: "GET",
cache: false,
dataType: "json",
async: true,
//timeout : 600000,
success: function(result, status)
{
// Do something
},
error: function(jqXHR, status, errorStr){
// Do something
}
});
}
java
#RequestMapping(value = "/doValidation", method = RequestMethod.GET)
public String processValidationResults(HttpServletRequest request, HttpServletResponse response,
#RequestHeader("Connection") String conn) {
ValidationResult validationResult = null;
JSONObject resultJson = new JSONObject();
HttpSession session = request.getSession();
JSONObject progressMap = (JSONObject) session.getAttribute("progressMap");
String uploadedFilePath = progressMap.getString("filePath");
String realMimeType = progressMap.getString("realMimeType");
long fileSize = progressMap.getLong("fileSize");
String ctxPath = request.getContextPath();
// INVOKE the VALIDATION ENGINE
try {
validationResult = validationEngineService.getValidationResult(uploadedFilePath, ctxPath);
resultJson = JSONObject.fromObject(validationResult);
} catch (Exception e) {
validationResult = null;
resultJson.put("errorMsg", e.toString());
}
try {
response.getWriter().print(resultJson);
response.flushBuffer();
} catch (Exception e) {
}
return null;
}
When you're working with HTTP, never expect a connection to take longer than half a minute.
Either use WebSockets or Comet (long polling).
See, there are many parties that might decide to stop your connection:
web browser, firewall/router/isp, web server (eg: Apache), server scripting language (eg: PHP)
The only time I disable this on the PHP side is when I want PHP to keep running even after the user stopped the connection (which, by the way, I have enable yet another setting).
Without some code, i'm not sure if i could help much but have you tried checking which event is triggering the ajax call? I made a silly mistake once by sending an ajax request on keydown, i later found out that instead of keydown , i needed to use keyup since thats the event triggered once the value of the textbox is set to the text + key recently entered.
So you could try a keyup or change the event in jQuery. If this is on localhost, its not a good sign....first determine whats causing the problem, the frontend or backend.
Things to do:
1) Change event type in jQuery
$("#elem").live("keyup",function() {//send req});
2) Check apache log. If your on ubuntu or something similar, you can go to /var/log/apache2/error.log
I am writing a Web chat application. It uses a long polling mechanism. Basically you send a request to the server, and the server holds it until there is data to send back. Then it responds, and then the client sends another request to the server. And the cycle repeats.
However, there is a problem - I have no error checking in place. What if the connection drops? Let's say I'm chatting with a friend and then my Wifi drops. Internet's down and let's say it goes back up a minute later. But then the long-polling mechanism has already died and with no polling, I have to refresh the page.
How can I implement an error checking mechanism to solve the problem of unsuccessful or dropped network connections? I am using jQuery to facilitate the Ajax requests if that helps.
*EDIT: Here is my JS code for the polling mechanism: *
// Polls the server for more data, basically a regular encrypted request
Minte.Network.poll = function()
{
// If client is not connected, do not send poll requests
if (!Minte.Client.connected)
return;
Minte.Network.request({ "action" : "poll"}, function(data) {
// If a client has disconnected and a poll returns afterwards, do not process it
if (!Minte.Client.connected)
return;
Minte.Network.lastPoll = Minte.clock.getTime();
Minte.Processor.process(data);
Minte.Network.poll();
});
};
// Send a regular, routine encrypted request
Minte.Network.request = function(data, callback)
{
$.post(SERVER_URI, data, function(data, textStatus, jqXHR) {
data = JSON.parse(data);
callback(data);
});
};
First off, you can hook the error handling of the ajax call. If it fails, you should eventually get an error condition back. Since I haven't seen this defined anywhere, you'd probably have to work out a way to test how all the different browsers respond when the connection is lost in different ways to see if this is something you could use exclusively. In any case, it won't hurt to hook the ajax failure response. You will likely also want to implement your own timeout so that if you haven't heard back from the server in xx time, then there must be some sort of problem.
Second off, if you want quicker feedback and more likely to be consistent even in different browsers, then you can have your server return a heartbeat. So, ever xx seconds of inactivity, your server would return a heartbeat response. The client would wait, xx + yy seconds (yy is some extra to allow for roundtrip time and any slight lag in the server response) and if it didn't receive either an actual datagram back from the server or a heartbeat response, then it would assume the connection has died. If it receives a heartbeat, it just makes another request again. You can set the heartbeat to whatever interval you want, though obviously short times are more taxing on the server infrastructure.
FYI, jQuery has a global ajax error handler described here: http://api.jquery.com/ajaxError#callback and the jQuery ajax call itself allow you to specify a timeout and an error handler.
In pseudo code:
$.ajax({
url: 'xxxx',
success: function(data, textStatus, jqXHR) {
if (data is heartbeat) start a new ajax connection to ask again
if (data has returned data in it) process it
};
error: function(jqXHR, textStatus, errorThrown) {
some sort of connection error has happened
};
timeout: 2 * 60 * 1000; // 2 minutes
});