Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if user has open more than one window or tab on the same session?

Tags:

javascript

I would like to detect if user has open more than one window or tab on the same session and if he did it - I would like to print an special information on screen.

This limte should oblige only in one special URL, so if user has open two tabs/windows with urls: http://page.com/limite.htm - I would like to print special information. When user has open two windows/tabs with urls: http://page.com/limite.htm and http://page.com/index.htm - everything is OK and I wouldn't show any informations.

Is it possible? Thanks.

like image 607
Newester Avatar asked Apr 07 '15 07:04

Newester


2 Answers

I think the best way to do it is with localStorage. http://www.gwtproject.org/doc/latest/DevGuideHtml5Storage.html

From the link, about localStorage:

Availability to other Windows/tabs: Shared across every window and tab of one browser running same web app

So, you could set an entry when the tab/window is open, and change it when it's closed. When another tab/window is open, you first check this entry value.

Obviously you need to be careful: browser crashes, for example, might not trigger the "on close" part, so the user wouldn't be able to open a new tab, even with none open (localStorage persists!). If you have server sessions, you can ask the user to login again (or run your auth process again), and reset this value. You can also try to use a sessionStorage entry to keep track of this kind of problem. From the link, about sessionStorage:

Persistence: Survives only as long as its originating window or tab.

Also, there is something called "Cross window messaging", that allow you communicate between tabs, but check if it's supported on the browsers you want to support.

http://ajaxian.com/archives/cross-window-messaging-with-html-5-postmessage

like image 93
gbuzogany Avatar answered Nov 15 '22 00:11

gbuzogany


I have done something very similar today. I hope this helps.

// helper function to set cookies
function setCookie(cname, cvalue, seconds) {
    var d = new Date();
    d.setTime(d.getTime() + (seconds * 1000));
    var expires = "expires="+ d.toUTCString();
    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

// helper function to get a cookie
function getCookie(cname) {
    var name = cname + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

// Do not allow multiple call center tabs
if (~window.location.hash.indexOf('#admin/callcenter')) {
    $(window).on('beforeunload onbeforeunload', function(){
        document.cookie = 'ic_window_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
    });

    function validateCallCenterTab() {
        var win_id_cookie_duration = 10; // in seconds

        if (!window.name) {
            window.name = Math.random().toString();
        }

        if (!getCookie('ic_window_id') || window.name === getCookie('ic_window_id')) {
            // This means they are using just one tab. Set/clobber the cookie to prolong the tab's validity.
            setCookie('ic_window_id', window.name, win_id_cookie_duration);
        } else if (getCookie('ic_window_id') !== window.name) {
            // this means another browser tab is open, alert them to close the tabs until there is only one remaining
            var message = 'You cannot have this website open in multiple tabs. ' +
                'Please close them until there is only one remaining. Thanks!';
            $('html').html(message);
            clearInterval(callCenterInterval);
            throw 'Multiple call center tabs error. Program terminating.';
        }
    }

    callCenterInterval = setInterval(validateCallCenterTab, 3000);
}
like image 29
Anthony Vipond Avatar answered Nov 14 '22 23:11

Anthony Vipond