I'm trying to perform a post query when the user leaves the page. The code I'm working with is
<script type="text/javascript">
window.onbeforeunload = function(){
var used = $('#identifier').val();
$.post('conversation.php?leave=true',{ud:used});
}
</script>
Is there anything wrong with what I'm doing here? The result I get in the FF error console is just saying that other non-related functions/variables are not defined (since they are unloading). Any tips or pointers for what I need to fix?
The simple answer is you can't make an asynchronous AJAX call in the beforeunload event reliably, it'll very likely be terminated before it finished, as the browser garbage collects the page. You can make a synchronous call, like this:
$.ajax({
type: "POST",
url: 'conversation.php?leave=true',
data:{ud:used},
async: false
});
Please don't do this though, as it traps your user in the page for longer than needed and prevents them from leaving, resulting in a negative experience. Note that this also locks up the browser while it executes, async: false should be avoided in every case possible.
Related
I want to add a class (this class put a spinner in an input, but thats not the problem) when the ajax poll takes more than x seconds (probably 1500 ms). I've tried with a setInterval and then, when the poll finishes I close the interval. But this didn't run.
I use jquery to do the ajax call and I use the property "async: false", this could be the problem? If I remove this my code doesn't run well so I need the ajax poll "sync".
Thats my code:
function calcvat(){
message_timer = setTimeout(function(){
$('.js-vatinput').addClass('changing');
}, 1000);
if(isValidVAT()){ //In this function is the ajax
....
}
}
function isValidVAT(){
...
$.ajax({
data: {...},
type: "POST",
dataType: "json",
async: false, //This could be the problem?
url: url,
}).done(function( data, textStatus, jqXHR ) {
...
$('.js-vatinput').removeClass('changing');
clearInterval(message_timer);
message_timer = false;
}
....
}
Thank you for your time!
Yes, the async: false is the problem. By using async: false, you force the browser to suspend the main UI thread while the ajax call is being done. No UI updates will be allowed, no other JavaScript code can run, etc., until the ajax call completes.
async: false is never correct. At best it makes for poor UX in any case (it freezes the tab at least, and also possibly other related tabs; on older browsers [such as IE8] it froze the whole browser UI).
Remove the async: false and (inferring from your code) just disable sending the form / performing the action that this validation is a part of while the ajax call is pending instead.
Side note 1: 1.5 seconds is a long time to wonder whether something is happening. Suggest feedback within 250ms at the latest; immediate feedback is generally better.
Side note 2: I assume message_timer is declared somewhere. :-) If not, the code is falling prey to what I call The Horror of Implicit Globals and you'll want to declare it somewhere that both of those functions have access to it (but not, ideally, globally).
I'm using jquery script which is refreshing a table on my website. It looks like that script is taking off all my memory after some time (checked on Firefox) - it depends how strong is my PC. How can I solve this or is it even possible ?
Here's code:
var url_one = './url_one';
var url_two = './url_two';
$(window).on("load", function() {
$.ajax({
cache: false,
timeout: 3000,
async: true
});
setInterval(function() {
$("#firstTable").load(url_one);
$("#secondTable").load(url_two);
}, (60000));
});
EDIT:
I've checked there is a warning in browser Console:
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help
http://xhr.spec.whatwg.org/
I can't find solution - mostly ppl say that async:false make that error but I've async: true;
it depends if problem is that memory keeps old results, or if number of calls increases and you retrieve multiple results at once.
i think you should check count of performed calls, lets say by printing into console each time function starts, and make sure they dont multiply.
you also could take a look at:
$.ajaxSetup({ cache: false });
or this ansver:
link
*setInterval() vs setTimeout()
Say I have this code here (somewhat pseudocode)
$.ajax({
url: "/api/user",
success: function(resp) {
var data = JSON(resp)
if (data.user.is_admin)
// do admin thing
else
// do something else
}
});
Basically the endpoint returns some info about the user and the callback handles the rest. Can I put a breakpoint before the if statement and change data.user.is_admin to be true before the statement is ran? Is that possible?
It is absolutely possible. You can't trust on client code for any security check. Anyone could play with it using something as simple as browser developer tools.
That kind of logic must be on server side, I'm afraid that you have no choice if you need yo keep that safe.
I'm working on a chat and I'm trying to figure out how I can detect that the user has left the page or not. Almost everything is being handled by the database to avoid the front end from messing up.
So what I'm trying to do is once the page is left for any reason (window closed, going to another page, clicking a link, etc.) an ajax call will be fired before a person leaves so I can update the database.
This is what I've tried:
$(window).unload(function(){
$.post("script.php",{key_leave:"289583002"});
});
For some odd reason, it wouldn't work, and I've checked the php code, and it works fine. Any suggestions?
Try this:
$(window).unload(function(){
$.ajax({
type: 'POST',
url: 'script.php',
async:false,
data: {key_leave:"289583002"}
});
});
Note the async:false, that way the browser waits for the request to finish.
Using $.post is asynchronous, so the request may not be quick enough before the browser stops executing the script.
This isn't the correct way of doing this... Suppose the OS just hangs or something happens in the browsers process then this event wont be fired. And you will never ever know when the user has left, showing him/her online ever after he/she has disconnected. Instead of this, what you can do is.
Try connecting a socket so that you can know the user is disconnected when the socket is disconnected
You can send a request to the server (say after every 1 sec) so that you can know that the user is still connected. If you didn't receive the request - even after 2 secconds - disconnect the user.
Try to add popup (prompt("leaving so early?")) after $.post. It may work. Tho it may be bad user experience. :)
This is related to the answer above. https://stackoverflow.com/a/10272651/1306144
This will execute the ajax call every 1 sec. (1000)
function callEveryOneSec() {
$jx.ajax({}); // your ajax call
}
setInterval(callEveryOneSec, 1000);
The unload event is not recommended to detect users leaving the page. From MDN:
Developers should avoid using the unload event ... Especially on mobile, the unload event is not reliably fired.
Instead, use the visibilitychange event on document and/or the pagehide event on window (see links for details). For example:
document.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'hidden') {
$.ajax({
type: 'POST',
url: 'script.php',
async:false,
data: {key_leave: "289583002"}
});
}
});
Better yet, use Navigator.sendBeacon, which is specifically designed for the purpose of sending a small amount of analytics data to a server:
document.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('script.php', {key_leave: "289583002"});
}
});
given to certain circumstances, I'm forced to keep page settings (Javascript-values) in the session and it has to be done right before leaving the page (I can't use cookies, since "pageSettings" can become quite large and localStorage is not an option yet ;) ). So this is how I tried it. However it seems that when I call the page directly again, the call of "http://blabla.com/bla" happens asynchronous, even though the async-attribute is set (I don't receive the settings of the previous call, but of the one before):
$jQ(document).ready(function () {
$jQ(window).unload(Main.__setSessionValues);
});
var Main = {
pageSettings: {},
__setSessionValues: function __setSessionValues() {
$jQ.ajax({
type: "POST",
async: false,
url: "http://blabla.com/bla",
data: {
pageSettings: Object.toJSON(Main.pageSettings)
}
});
}
};
Does anyone know what the problem might be?
thanks in advance
The code looks fine. You might try bind('beforeunload', ...) rather than unload, to grab things as early as possible. But of course, if something else also hooks beforeunload and the unload gets cancelled, your call will have been made even though you're still on the page.
Slightly off-topic, but if you can possibly find a different way to do this, I would. Firing off synchronous ajax calls when the user is trying to leave the page is not ideal.