I have a small problem: I need to detect if the user of my website has not carried out any Ajax POST request in a set time frame, and give him a prompt to do something about it. I already have a code as follows:
var idleCounter = 600
var loginTimeoutCounter = setInterval(function() {
console.log(idleCounter)
// If a POST request is detected, reset idleCounter to max value.
if (idleCounter > 0) {
idleCounter -= 1
} else {
var promptAboutLogout = confirm('You have been idle for more than 6 hours.\n\n' +
'Your login session could have expired by now.\n\n' +
'Please be sure to refresh this web page before attempting to upload new content.\n\n' +
'Press OK to reload this page, or Cancel to stay on it as-is.')
if (promptAboutLogout) {
clearInterval(loginTimeoutCounter)
location.reload() // Reload the web page to refresh the login credentials.
} else {
idleCounter = 600 // Re-set the counter for 10 min to give user another prompt.
}
}
}, 1000)
I just cannot figure out how to neatly add in a code for POST request detection. I do not want to glue in idleCounter value modification in a form submit eventListener a few hundred lines earlier, because it will be messy, and difficult to come back to when the code will go through the next revision in any foreseeable future.
Is there any neat JS function which picks up occurrence of any POST request?
The approach you are using would make more sense if you want to prompt the user before the session is about to expire and not after the session has expired. However if you want to continue using this approach you should have a common controller/util(consider it a wrapper over the lib you are using for ajax requests) from where you fire all your ajax requests. So whenever you want to invoke an ajax request, you pass the details to the controller which in turn wil make the actual ajax request. It would then receive the response from server and pass it to the callee for further processing. Here you can handle your timer variable for every post request.
Now if your are using a common controller you can get rid of this timer thing all together. When the session will expire, you server will redirect to the login page, mostly with status code 302. Your browser will handle this redirect request and serve your ajax callback with the html of the login page. At this point you can prompt your message dialog or event better display the login screen so that user can reauthenticate and continue his work from there. This should be some amount of code change but should surely ease things in future.
Related
$('#gd').on('click', function(){
// move up and down DOM elements
// some ajax procedure to store new values on database (php/mysql)
});
Is there any danger to repeating this click very quickly for a long time?
For example - if the connection is poor - will the ajax will not complete each time?
I tested on my live server - seems there is no problem, but... I'm still concerned.
And what is the way to avoid possible problems it this scenario - i.e. if a user keeps clicking very quickly on the #gd button.
This "Danger" would be more accurately described as undesired behavior. However, it is indeed issue which should be treated - as sending multiple request when only 1 is required would consume resources on both client and server with no reason.
If you would like to prevent the user from clicking the button while the request is being processed, disable the button after the client send it it, and re-enable it after response processing complete:
$('#gd').on('click', function(){
// 1. do some stuff with DOM
// 2. disable button + make ajax call
$.ajax({someRequestOptions})
.always(function() {
// 3. re-enable button
});
});
Working on a platform, to enable auto-ticketing functionality. For which a REST API request is used for ticket creation. Unfortunately, there are 2 requests popping simultaneously, which results in creating duplicated tickets.
How to handle such case and send only one of these requests?
Tried adding the 2nd request in the response callback of the first, though this does not seem to work.
if (flag == 1){
logger.debug("Node-down alarm-Request raised - +sitn_id);
clearTimeout(mouseoverTimer);
mouseoverTimer = setTimeout(function(){
logger.debug("Inside Call back function - ");
//function call for ticket creation
incidentRequest(sitn_id,confUtil.config.mule_url);
}, 10);
You really should show more of the code that makes the request, though it seems as if you are doing some ajax inside your 'incidentRequest', so I will presume that (if that isn't what you are doing, then please, show your code....) - and since you tags say javascript and jquery - well, here goes...
To stop the 'double send' in an AJAX call, it is simple:
function incidentRequest(sitn_id,confUtil.config.mule_url){
// stop the double by clearing the cache
$.ajaxSetup({cache: false});
// continue on with the AJAX call
// presuming the url you want is confUtil.config.mule_url
// and the data you want to send is sitn_id
$.post(confUtil.config.mule_url, 'sitn_id=' + sitn_id, function (data) {
// do cool stuff
});
}
Hopefully that will help you get moving. If not, then we will need more code of what is going on around all this.
I was reading this question: Trying to detect browser close event
But it's not comprehensive enough, or at least I'm not sure it is, I need to detect when the user leaves the website, this could be:
internet died
PC shuts down (power outage for example)
user close the browser
user close the browser tab in which the website was running
I'm sure there are more cases.
This probably needs to be managed by the server, and not some javascript event that is not going to be fired in extreme cases.
Any ideas what could be used in this case?.
You could use socket.io and listen for when the socket is lost, or you could have your site send a heartbeat to the server and if X milliseconds goes by without a pulse, you can assume the user left for any of the reasons you listed.
I am using Java Script to detect the event of leaving and sending an ajax request to my server so I can store that the user left the page.
The second part is to detect the time the user is in my page, every 3 seconds I also send a ajax request to my database to save the time of the user in the page.
<script>
window.onbeforeunload = function(){//If user left the page
user_left_page();
};
function user_left_page(){//USER LEFT THE PAGE send data to php to store into my database
var action = "left_page";
$.ajax({
url:"includes/track-page-time.inc.php",
method:"POST",
data:{ action: action},
success: function(data){
},
});
}
//This one below is to store the time the user is spending in your page. I am using both
// in my code, basically I keep storing the data every 3 seconds to know the time
setInterval(function () {
update_user_activity();
}, 3000);//Interval time to send the info to the database
function update_user_activity(){//IS USER IN THE PAGE?
var action = "update_time";
$.ajax({
url:"includes/track-page-time.inc.php",
method:"POST",
data:{ action: action},
success: function(data){
},
});
}
</script>
Another simple method you can track the IP/Session Id and save in the Database, you may update the time in the db using the ajax call in an interval i.e every 5 or 10 minutes.
if user not taken any activity and the time will not be updated, if time in db is less than the time() - $intervals , then you can assume that the user has left, lost connectivity etc.
You could use the window.onbeforeunload for the last two cases i.e. detecting the browser close or tab close event. For the first two events that is power failure or connectivity problems, only continuously ping or like AlienWebguy said the heartbeat mechanism can be implemented.
window.onbeforeunload = confirmExit;
function confirmExit()
{
return "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?";
}
Ref site
Hi i have to perform perform like, when the ajax is in progress, then do not allow the user to do page refresh.
here is the code i have
$('#submit').click(function() {
$(function() {
$(".col1").mask("Generating csv...."); //This will generate a mark, Here i would like to prevent the user from doing any sort of operation.
var to = $('#filters_date_to').val();
var from = $('#filters_date_from').val();
$.ajax({
url:"../dailyTrade/createCsv?filters[date][to]="+to+"&filters[date][from]="+from,success:function(result){
if(result) {
$(".col1").unmask(); //Here we can unlock the user from using the refresh button.
window.location = '../dailyTrade/forceDownload?file='+result;
setTimeout('location.reload(true);',5000);
}
}
});
});
});
Any suggestions.
Best you can do is use onbeforeunload to present the user with a message saying that a request is in progress and asking them if they are sure they want to proceed.
e.g.
var req;
window.onbeforeunload = function() {
if(req) {
return 'Request in progress....are you sure you want to continue?';
}
};
//at some point in your code
req = //your request...
You cannot, in any way, prevent the user from leaving your page using JS or anything else.
I doubt if you should do that.
$(window).bind('beforeunload',function(){
return 'are you sure you want to leave?';
});
If you are talking about a refresh "html button" on your web page, that can easily be done. Just before you make your ajax call, disable your refresh button and on success/error function of the ajax call enable it.
Disable button
$("#refreshBtn").attr("disabled", "disabled");
Enable button
$("#refreshBtn").removeAttr("disabled");
You cannot do it just by inserting JavaScript code.
Only ways I can think of are:
Use synchronous ajax call, on that way browser should freeze (however it will notify user that script is taking too long to process and user will be able to stop execution)
Write browser plugin that will modify browser behavior (eg. prevent refreshing page for url that you preset)
Both ways are ugly and I wouldn't recommend doing it.
You should modify your script so it can resume execution if page has been refreshed (use HTML5 localStorage).
http://www.w3schools.com/html/html5_webstorage.asp
In your case, I would put in localStorage simple state (boolean) to check did ajax call happened or not. If it did happened, then just try calling again same url and you will get file name. But on server side (if you haven't done already) you should implement caching, so when same url is called twice, you don't need to make two separate files, it could be same file (server will be much lighter on hardware resources).
I have a upvote button, which the user can press and a vote will be registered. On clicking this button again, the vote gets cancelled.
So each press of this button is doing a DataBase Write. If an autoclicker is used on this button continuously, continuous DB calls will happen. I want to prevent this.
What can I do?
PS. I am sending an ajax query to the backend(running Django) when the upvote button is clicked.
You'd really want to check this on the server, so it doesn't matter if someone disables javascript.
If you're using PHP one option is to set a time limit between votes.. eg only allow one vote per minute.
So on every vote, store the time of the vote in a session variable, then ignore subsequent votes if it is within the time limit:
//on vote
$now=date('U');
if(!isset($_SESSION['lastvote']) || $now - $_SESSION['lastvote']<LIMIT){
$_SESSION['lastvote']=$now;
// do database call
}else{
//throw error
}
Probably the easiest approach is to disable the buttons while a single operation is running.
To obtain this, assuming you're using a JQuery ajax request to call the "upvote" / "downvote" method you simply have to:
$("#upvoteButton").click(function)
{
$("#upvoteButton").attr("disabled");
$.ajax({
url: 'url/upvote.extension',
success: function(data) {
$("#upvoteButton").removeAttr("disabled");
}
});
}
This way a single request is send & resolved per single tab / window.
If you trust that your users accept cookies, you could store the click together with the object id and a timestamp in the session, and test whether the user clicked the vote button during the last n seconds.
You also could disable the vote button on the web page with javascript, and enable it again after n seconds to revoke the vote.
Both suggestions are dependent on users who use a javascript enabled or cookie enabled browser.
If you have to take bots into consideration who just send the url repeatetly to the server, you need to take a different approach - e.g. check whether the current ip address has called the url in the last n seconds and raise a 403 Forbidden http error or something.
If you can use setTimeout you can try something like this:
var toggleVote = (function () {
var voted = false,timeout;
return function () {
if( timeout )
clearTimeout(timeout)
voted = !voted
timeout = setTimeout(function() {
console.log("Ajax call - vote : " + voted)
},400)
}
})()
document.getElementById("vote").addEventListener("click",toggleVote)
Heres an example on JSBin
Try mashing the "Click me" div
Easy way:
<button id="upvote" onclick="upvote(this)">Up</button>
<script>
var upvote = function(x){
$(x).removeAttr('onclick'); //if you click this button again, it will do nothing
//call ajax to do something here...
//...............
//after finishing, add attribute onclick to the button
$(x).attr('onclick', 'upvote(this)')
};
</script>