Preventing error 503 on JQuery load - javascript

This is my code on shoutbox update :
function updateShoutbox(){
$("#shoutdiv").load("shoutbox.php", { 'action': 'update' } ,
function (responseText, textStatus, req) {
if (textStatus == "error") {
return false;
}
});
}
$(document).ready(function(){
updateShoutbox();
var auto_refresh = setInterval(
function ()
{
updateShoutbox();
$("#shoutdiv").scrollTop($("#shoutdiv")[0].scrollHeight);
}, 6000);
It returns error each some minutes :
shoutbox.php returned error:
Service Unavailable
Is there anyway to handle this error and hide it somehow ?
I edited my code so to stop showing any error on shoutbox update, but it still shows this error each minutes.

Ok, so let's take this for example:
$(document).ready(function(){
(function iterate(i) {
if (!!i) {
console.log('iteration #', i--);
setTimeout(function next(){
iterate(i);
}, 1000);
}
})(10);
});​
http://jsfiddle.net/userdude/6C8yp/
If you look at the console, you'll see it counts down until i is equal to 0, or i is not given (that's what the !! is for there). What I'm doing here is looping each second, but only after the last loop has finished. I'm feeding my loop.
Looking at what you have here, I might do this instead:
$(document).ready(function($){
var $shoutbox = $("#shoutdiv"),
timer;
(function update(){
var opts = {
url: 'shoutbox.php',
action: 'update',
complete: wait
};
$.ajax(opts);
function wait(res, status, req){
if (status == 200) {
$shoutbox
.append(res)
.scrollTop($shoutbox[0].scrollHeight);
timer = setTimeout(update, 6000);
}
}
})();
});​
http://jsfiddle.net/userdude/whsPn/
http://jsfiddle.net/userdude/whsPn/1/
Ok, so what we have above should mostly emulate the code you have in the question. You'll note that I have the complete: wait part in there, and the setTimeout() is in that callback. And.. it's only called if the status returned is 200 (success).
Now, there you could turn complete: wait to success: wait, and take out the status == 200 if statement altogether. Of course, if you do want to run the update again, but maybe do something different, this is your chance.
Also note, in the fiddle linked I've got some dummy code in there. So don't just copy/page what's in the fiddle, or you'll have errors and it won't run at all.
EDIT: Oops, found an error with url =. Fixed.

If you want to "hide" your error instead of looking for the cause of the error in the first place, try this in your callback function in the $.load:
function (responseText, textStatus, req) {
if(req.status!=200&&req.status!=302) {
return false;
}
//update the shoutbox
}
At least to me this is what seems to be the most reliable way to prevent random errors from getting through your checks.

Related

Best way to request data from server every x seconds

I created a very simple example. I try to request a value from my server every X seconds, in this case i simply want to get a random number, every second.
This solution works, but unfortunately there seems that an infinite loop occurs after a while, which leads to a crash. I also get over 100k Errors after a while net::ERR_INSUFFICIENT_RESOURCES.
request_data(1000);
function request_data(intervall) {
$.post('ajax.php', {
cmd: "get_random_number"
}, function (returned_data, status) {
if (status === "success") {
$("#result_output").html(returned_data);
setInterval(function() {
request_data(intervall);
}, intervall);
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="result_output></p>
// ajax.php
<?php
$cmd = filter_input(INPUT_POST, "cmd");
if (isset($cmd) && $cmd == "get_random_number") {
echo rand(5, 15);
}
Whats the best solution to achieve this?
You could do a setInterval, and then inside this do an ajax call. One of the parameters you can set in the $.ajax is a timeout - so that you can stop multiple ajax calls stacking up and causing problems.
$.ajax({
url: '',
type: '',
data: {},
timeout: 3000,
success: function(data){
// do stuff
}
});
For more info on the parameters, see http://api.jquery.com/jQuery.ajax/
As Derek has pointed out, this is because, you are making 2^n calls since the setInterval is inside the function itself.
Try it like this instead
window.setInterval(1000, request_data);
function request_data() {
$.post('ajax.php', {
cmd: "get_random_number"
}, function (returned_data, status) {
if (status === "success") {
$("#result_output").html(returned_data);
}
});
}
I solved it by simply replacing setInterval with setTimeout.

getting connection reset after sending a jquery ajax $.post

I am making a game lobby with php, jquery, ajax.
I have php echo a string that is a jquery loop that sends ajax $.post's to another page to check and see if some one joined the players game, if new users are online and to get current games to join. if there is then I fill div's on the page with the new data.
here is the loop
<script>
$(function() {
getPage = function() {
// this gets all current games users are trying to start up
$.post("lobbyClasses.php",
{
lobbyRequest: "getGames",
},
function(data, status){
if(status == "success"){
$("#joinGameContainer").html(data);
// this gets all online users and puts themin a div onlineUsers
$.post("lobbyClasses.php",
{
lobbyRequest: "getOnlineUsers",
},
function(data, status){
if(status == "success"){
$("#onlineUsers").html(data);
// start it again;
setTimeout(function(){
getPage();
}, 5000);
}else{
// get all online users failed start loop again
$("#onlineUsers").html("failed...");
setTimeout(function(){
getPage();
}, 5000);
}
});
}else{
//get all games failed start loop again
$("#joinGameContainer").html("failed...");
setTimeout(function(){
getPage();
}, 5000);
}
});
}
getPage();
});
</script>
The problem is that this loop only works sometimes and others the browser(chrome and firefox) will stall and give an error (connection reset in firefox)(no data returned in chrome) I thought that nesting the post request might help and it did significantly but it still happens from time to time. It also happens a lot more when i send another post to a different page such as the following ....
$("#makeGame").click(function(){
getGame = function() {
$("#scripts").html("getting data...");
$("#onlineUsers").html("getting data...");
$("#joinGameContainer").html("getting data...");
$("#gameContainer").html("getting data...");
//alert("newgame was clicked.");
$.post("cardgameclasses.php",
{
gameRequest: "makeGame",
},
function(data, status){
// the code stalls here and dose nothing then the browser error happens
//alert("Data: " + data + "\nStatus: " + status);
if(status == "success"){
$("#scripts").html(data);
}else{
$("#scripts").html("failed...");
setTimeout(function(){
getGame();
}, 5000);
}
});
}
getGame();
so I thought that replacing the loop with text then sending the post would help and it did a little bit but on occasion i still get a browser error connection reset. i am not sure what i am doing wrong please help.
I figured out what was going on with my code PHP only allows so many post vars to a single page to prevent denial of service attacks. I was sending too many posts. I also realized that every thing I was trying to update with ajax could be updated with a single post instead of 4 nested posts. The processing of the data can be done on server side. If you are making several posts for one page you are doing something wrong. The proper code would be this:
function myTimer() {
$.post("lobbyClasses.php",
{
lobbyRequest: "getContent1",
},
function(data, status){
if(status == "success"){
$("#lobbyContent").html(data);
}else{
$("#lobbyContent").html("failed...");
}
});
}
myTimer();
var myVar = setInterval(function(){ myTimer() }, 5000);
function myStopFunction() {
clearInterval(myVar);
}
var newarray = [];
var dateandtime = Date.now();
newarray.push(dateandtime);
function myTimer() {
if( newarray[0] + 1000 < Date.now()){
$.post("lobbyClasses.php",
{
lobbyRequest: "getContent1",
},
function(data, status){
if(status == "success"){
$("#lobbyContent").html(data);
}else{
$("#lobbyContent").html("failed...");
}
});
newarray[0] = Date.now();
}
}
myTimer();
var myVar = setInterval(function(){ myTimer() }, 5000);
function myStopFunction() {
clearInterval(myVar);
}

Detect when any ajax calls fail

I have a website where users can work on projects and their work gets automatically saved to my database. Every couple seconds on my site an ajax (post) call occurs (usually in jquery) to check permissions and what not.
With one section of code is there any way so check if any of the ajax calls on your page fail. I don't want to have to go to every individual call and add a block of code to the end.
Basically this is so I can alert the user if they have lost connection or if something is going wrong.
You can use the jQuery event ajaxError. It will be triggered whenever an Ajax request completes with an error:
$(document).ajaxError(function() {
console.error('Error');
});
Check out the documentation.
$(document).ready(function(){
//ajax setup settings
$.ajaxSetup ({
cache: false,
async: false,
statusCode: {
404: function() {
alert('Page not found!');
},
500: function(jqXHR, textStatus) {
alert('Server side: ' + textStatus);
}
}
});
});
I hope this may help you
I would suggest you to override the original jquery ajax function.
var $_ajax = $.ajax; // reference to original ajax
$.ajax = function(options) {
if (options.error) {
// reference to original error callback
var originalErrorHandler = options.error;
var errorHandlerContext = options.context ? options.context : $;
var customErrorHandler = function(xhr, status, error) {
// notify error to your user here
};
// override error callback with custom implementation
options.error = customErrorHandler;
};
return $_ajax.apply($, arguments);
}

Running ajax on page load and then every 5 seconds

I still find it hard to grasp some of the javascript/jquery concepts.
I wanted to find a way of loading ajax on page load and then every 10 seconds after that. I stumbled upon http://www.erichynds.com/blog/a-recursive-settimeout-pattern which suggested is a good idea as it provided some error detection to stop script running if ajax fails, only problem is that on page load, it must wait 5 seconds before requesting data, I want it to request data every 10 seconds, as well as on page load, so I don't have to wait 10 seconds before seeing anything.
How do I get it to load on page load aswel as every 10 seconds after that?
I tried adding the following:
if(this.success_count&&this.failed == 0)
{
jQuery.proxy(this.getData, this)
}else{
setTimeout(
jQuery.proxy(this.getData, this),
this.interval
);
}
To this:
var poller = {
failed: 0,
success_count: 0,
interval: 10000,
init: function(){
if(this.success_count&&this.failed == 0)
{
jQuery.proxy(this.getData, this)
}else{
setTimeout(
jQuery.proxy(this.getData, this),
this.interval
);
}
},
getData: function(){
var self = this;
jQuery.ajax({
url : "foo.htm",
success : jQuery.proxy(self.successHandler, self),
error : jQuery.proxy(self.errorHandler, self)
});
},
// => Handle Success
successHandler : function( response ){
if( response === "failure" ){
this.errorHandler();
} else {
++this.success_count;
this.init();
}
},
errorHandler: function(){
if( ++this.failed < 5 ){
this.interval += 1000;
this.init();
}
}
};
poller.init();
I then also tried this, but it requests the data twice, understandably once for each.
poller.getData();
poller.init();
Put it in a document ready function using jquery to fire it off at the beginning of the page load and then also have a setTimeout function that calls the ajax call every 10 seconds. See below for an example.
$(document).ready(function() {
ajaxFunctionCall();
setTimeout( ajaxFunctionCall, 10000 );
});
call the function on load, clear it and add settimeout inside the function
var tr=null;
$(function(){
tr=setTimeout(function(){timerFunction();},100);
});
function timerFunction(){
clearTimeout(tr);
//insert following after success
tr=setTimeout(function(){timerFunction();},10000);
}

Multiple ajax Allow only latest call

I have an input box on which there is an ajax request on every key press. so if i enter word "name" there will be 4 successful request. So i actually want only the latest request of executed. so if i enter word "name" there will be only one request which will be the last one.
and i also have a solution for this (this is a simple example with click method)
JS script
var callid = 1;
function ajaxCall (checkval ){
if(checkval == callid){
$.ajax({
type: 'post',
url: baseurl + "test/call_ajax",
data: {
val: "1"
},
success: function(data) {
console.log(data)
}
});
}
}
function call(){
var send = callid+=1;
setTimeout( function(){ ajaxCall(send) } , 500);
}
html script
<a href="#" onclick="call()" > Call ajax </a>
This is working perfectly. But i was think if there is way to refine it a little bit more.
Any ideas :)
I am sure you are looking some better intent technique for event dispatching.
var eventDispatcher = null;
$('.textbox').keyup(function(){
if(eventDispatcher) clearTimeout(eventDispatcher);
eventDispatcher = setTimeout(function(){
$.ajax({ ... });
}, 300);
});
You could do your ajax inside of a setTimeout. So you don't need to declare and check an additional variable or write another function like call()
$(document).ready(function () {
var timer;
$('#fillMe').keypress(function () {
clearTimeout(timer);
timer = setTimeout(function () {
//replace this with your ajax call
var content = $('#fillMe').val();
$('#result').text('You will only see this if the user stopped typing: ' + content);
}, 1000); // waits 1s before getting executed
});
});
<input type="text" id="fillMe">
<div id="result"></div>
On every keypress event this clears the timeout and immediately creates a new timeout. This means the content of the setTimeout function only gets executed if the user stopped typing for at least 1 second.
Of course 1 second is just the value for the example purpose. You can change it to whatever you want or think is a good time (like 500ms)
See my jsfiddle
setTimeout returns an id that you can store and use to clear the previously set timer:
var timerId;
function call() {
if (timerId !== undefined) {
clearTimeout(timerId);
}
timerId = setTimeout( function() { ajaxCall(send) }, 500);
}
The result of this should be that the ajaxCall method will be called 500ms after the last letter is entered.

Categories