views:

80

answers:

7

Basically, once a user leaves a webpage in my application, I need to call a PHP script with AJAX, which will insert a time spent on the webpage to the database and then leave the page.

It is important to wait for the AJAX request to finish because webpages in my application are not accessible to users unless they have spent a certain time on a previous page (let's say two minutes).

Here is my jquery code:

$(document).ready(function() {

    var teid = TEID;
    var startTime = new Date().getTime();

    $(window).unload(function() {
        var timeSpentMilliseconds = new Date().getTime() - startTime;
        var t = timeSpentMilliseconds / 1000 / 60;

        $.ajax({
            type: 'POST',
            url: '/clientarea/utils/record-time',
            data: 'teid=' + teid + '&t=' + t
        });
    });

});

How should I change it so it will wait for the AJAX request to end before leaving the webpage?

EDIT:

Or it might be better (easier) to just let the AJAX request be repeated every minute or so. Is that possible?

A: 

Well, you can set async: false on your AJAX call to make the browser wait for the request to finish before doing anything else, but note that this will 'hang' the browser for the duration of the request.

$.ajax({
    type: 'POST',
    async: false,
    url: '/clientarea/utils/record-time',
    data: 'teid=' + teid + '&t=' + t
});

From the manual:

By default, all requests are sent asynchronous (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.

Tatu Ulmanen
Hmm. Thanks. I have updated my question. It might be easier to just let the AJX request repeat every let's say minute. How would I do that?
Richard Knop
I'd strongly recommend to avoid that, **especialy** on `unload`.
jAndy
I agree with jAndy...
Reigel
A: 

The best way to have users spend time on your pages is to have interesting content...

Claude Vedovini
+1  A: 

for me, yours is not a good idea for the browser to wait before closing...
simply because what if I really want to close it?...

if a page bother a user, it's not good...

my suggestion is, in the page, you wait for 2 minutes (if 2 minutes is the requirements), then send an ajax that the user has done his 2 minutes...

you can then check it on the server side if one has his 2 minutes or not...

Reigel
+1  A: 

The jQuery.ajax() method has the option async. If you set it to false the call will block until the response comes back (or it timed out). I'm pretty shure, that calling this, will yause the browser to weit in the unload handler.

Side note: You can't rely on this to work. If the browser gives the user the option to cancel the unload handlers (which some browsers do after a while of waiting), the "time spend on site" will never be updated. You could add a timer to the site, which periodically calls a script on the server and which updates the time. You won't have an accurate value, but in your case, this isn't needed.

If you only need to know if the user was X seconds on the page You could simply set a timeout in the onload handler (using setTimeout(function, ms)) which makes a call if the user has spend the needed time. So there would be no need for a unload handler.

Martin
+1  A: 

use onbeforeunload:

$(document).ready(function(){
  window.onbeforeunload = function(){
     // $.ajax stuff here
     return false;
  }
});

This will at least bring the user a messagebox which asks him if he wants to close the current window/tab.

jAndy
+1  A: 

I think it would be much better to use a polling technique as you suggest, though it will cause some load on the web server.

$(document).ready(function() {

    var teid = TEID;
    var startTime = new Date().getTime();

    var ajaxFunc = function() {
        var timeSpentMilliseconds = new Date().getTime() - startTime;
        var t = timeSpentMilliseconds / 1000 / 60;

        $.ajax({
            type: 'POST',
            url: '/clientarea/utils/record-time',
            data: 'teid=' + teid + '&t=' + t
        });
    };

    setInterval(ajaxFunc, 60000);

})

You'll be glad when you can use websockets :)

sje397
Thanks. But this will only get executed once after one minute? Could it execute repeatedly every minute (60 seconds)?
Richard Knop
That's what setInterval does, as opposed to setTimeout
sje397
+1  A: 

It is a bad idea to try and hijack your users' browser, since it will give them a bad feeling and send them away.

If for some reason you want not to produce a new page until the user has spent a minimum time on the previous one, the best thing to do is to pilot server side, i.e. redirecting to the current page until the requested time has passed.

You don't even need to make ajax calls, just store in the session the timestamp of when the page was served, and don't show the following page until a certain amount of time has passed.

Be sure to tell the users they have to wait for a new page to be ready, maybe with a simple javascript countdown.

If you want the user to actually have the page active for a certain amount of time (i.e. not to switch to another tab/window waiting for the two minutes to elapse), well, I cannot propose an effective solution.

Iacopo