I\'m wondering if it is possible to determine if a user already has a web browser open to the web application I\'m working on. It seems that they can open several instances
We have implemented a solution to this problem on the slicethepie.com. Users (or "scouts") are only allowed to have one browser window open at a time to ensure they listen to the music they are being paid to review.
When a scout requests the first track to review in their scouting session we set a new Guid on their account and return this "key" along with the details of the track they're being given to review. It happens that the recipient of this key is a flash movie, but it doesn't have to be. The key is re-submitted along with the scout's review, and we check to see if it matches the saved key. If it doesn't they've started a new scouting session in a new window.
I'm not implying this method is foolproof, but it could be adapted to your needs quite easily.
I have a js code and this code only let you have one instance of your page but only in the pages that run this js code. Example: if you put the js code in page1.html and page2.html, the code will permit one instance of page1 OR page2. If you only puts the js in page1, page1 will have only one instance, while page2 will have multiple instances.
Just copy&paste in your site and change the last lines for your logic.
Code:
var statusWindow = document.getElementById('status');
(function (win) {
//Private variables
var _LOCALSTORAGE_KEY = 'WINDOW_VALIDATION';
var RECHECK_WINDOW_DELAY_MS = 100;
var _initialized = false;
var _isMainWindow = false;
var _unloaded = false;
var _windowArray;
var _windowId;
var _isNewWindowPromotedToMain = false;
var _onWindowUpdated;
function WindowStateManager(isNewWindowPromotedToMain, onWindowUpdated) {
//this.resetWindows();
_onWindowUpdated = onWindowUpdated;
_isNewWindowPromotedToMain = isNewWindowPromotedToMain;
_windowId = Date.now().toString();
bindUnload();
determineWindowState.call(this);
_initialized = true;
_onWindowUpdated.call(this);
}
//Determine the state of the window
//If its a main or child window
function determineWindowState() {
var self = this;
var _previousState = _isMainWindow;
_windowArray = localStorage.getItem(_LOCALSTORAGE_KEY);
if (_windowArray === null || _windowArray === "NaN") {
_windowArray = [];
}
else {
_windowArray = JSON.parse(_windowArray);
}
if (_initialized) {
//Determine if this window should be promoted
if (_windowArray.length <= 1 ||
(_isNewWindowPromotedToMain ? _windowArray[_windowArray.length - 1] : _windowArray[0]) === _windowId) {
_isMainWindow = true;
}
else {
_isMainWindow = false;
}
}
else {
if (_windowArray.length === 0) {
_isMainWindow = true;
_windowArray[0] = _windowId;
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(_windowArray));
}
else {
_isMainWindow = false;
_windowArray.push(_windowId);
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(_windowArray));
}
}
//If the window state has been updated invoke callback
if (_previousState !== _isMainWindow) {
_onWindowUpdated.call(this);
}
//Perform a recheck of the window on a delay
setTimeout(function () {
determineWindowState.call(self);
}, RECHECK_WINDOW_DELAY_MS);
}
//Remove the window from the global count
function removeWindow() {
var __windowArray = JSON.parse(localStorage.getItem(_LOCALSTORAGE_KEY));
for (var i = 0, length = __windowArray.length; i < length; i++) {
if (__windowArray[i] === _windowId) {
__windowArray.splice(i, 1);
break;
}
}
//Update the local storage with the new array
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(__windowArray));
}
//Bind unloading events
function bindUnload() {
win.addEventListener('beforeunload', function () {
if (!_unloaded) {
removeWindow();
}
});
win.addEventListener('unload', function () {
if (!_unloaded) {
removeWindow();
}
});
}
WindowStateManager.prototype.isMainWindow = function () {
return _isMainWindow;
};
WindowStateManager.prototype.resetWindows = function () {
localStorage.removeItem(_LOCALSTORAGE_KEY);
};
win.WindowStateManager = WindowStateManager;
})(window);
var WindowStateManager = new WindowStateManager(true, windowUpdated);
function windowUpdated() {
//"this" is a reference to the WindowStateManager
//statusWindow.className = (this.isMainWindow() ? 'main' : 'child');
if (this.isMainWindow() === false) {
//alert("This is not the main window")
location.href = "yourpage.html";
}
else {
//alert("This is the main window")
}
}
//Resets the count in case something goes wrong in code
//WindowStateManager.resetWindows()
You can stop the page functionality when user opened another tab or another window or even another browser
$(window).blur(function(){
// code to stop functioning or close the page
});
<script type="text/javascript">
window.onload = function(){
if (document.cookie.indexOf("_instance=true") === -1) {
document.cookie = "_instance=true";
// Set the onunload function
window.onunload = function(){
document.cookie ="_instance=true;expires=Thu, 01-Jan-1970 00:00:01 GMT";
};
// Load the application
}
else {
alert(" Security Alerts.You Are Opening Multiple Window. This window will now close.");
var win = window.open("about:blank", "_self"); win.close();
// Notify the user
}
};
</script>
If someone copy the website url and paste it in a new window or tab, the browser history for that window/tab will be empty... so you can use javascript and check the history..
if (history.length == 1) { //0 for IE, 1 for Firefox
// This is a new window or a new tab.
}
Now you can prompt the user to close the tab, or disable that page (by making all elements disabled
for example).
I partially solved the problem this way. My app ask users for authentication... so they type in a username and a password. When they click the submit button I store both data into session variable, i.e. I store username into Session("LoginName").
So here is the trick: just test if Session("LoginName") has a value BEFORE user enter it, in the page load event of login page. If so, this is a multiple session and you can stop the user or whatever.
Something like (I use VB):
If Not Page.IsPostBack Then
Try
If Session("LoginName") <> "" Then
Response.Redirect("www.mysite.com")
Exit Sub
End If
Catch ex As Exception
' Do something
End Try
PRO: very simple
CON: user can copy the address of an inner page and paste it to another tab of the same browser... this is why I said "partially"