1

I am working on an Angular Application build using Angular 7. We don't allow users to open our application in multiple tabs of a browser and I am using LocalStoage+SessionStorage to make this happen.

app.component.ts

//This function is being called on component loading
register_tab_GUID() {
// detect local storage available
if (typeof (Storage) !== "undefined") {
  // get (set if not) tab GUID and store in tab session
  if (sessionStorage["tabGUID"] == null){
     sessionStorage["tabGUID"] = this.tab_GUID();
  } 
  var guid = sessionStorage["tabGUID"];

  // add eventlistener to local storage
  window.addEventListener("storage", (e) =>{

  if (e.key == 'tabGUID') {
     if (e.oldValue != e.newValue) {
        this._api.logout();
        localStorage.setItem('multiTabs' , 'true');
        this.router.navigate(['multi-tabs-not-allowed'])
      }
    }
  }, false);

      // set tab GUID in local storage
      localStorage["tabGUID"] = guid;
    }
  }



tab_GUID() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
  s4() + '-' + s4() + s4() + s4();
}

Everything works fine when user opens a new tab and tries to open the application. But when user duplicates already opened tab I found that SessionStorage does not clear and it has the same data saved as previous tab that we duplicated.

Duplicating Tab

I tried searching for this behaviour of SessionStorage but couldn't find anything related to this. Is this the accurate behaviour or I am doing something wrong?

Adnan Sheikh
  • 760
  • 3
  • 13
  • 27
  • How about clearing the session storage on every tab load, in that way you will be sure if the tab is newly opened or duplicated. – Gopesh Sharma Jul 03 '19 at 10:44
  • 1
    I don't think that you can avoid this with `duplicate`, because it's seems to copy and past everything from your old tab, included sessionStorage. – Shifenis Jul 03 '19 at 10:46
  • 1
    [this](https://stackoverflow.com/a/28120936/5621827) may help – jitender Jul 03 '19 at 10:47
  • @GopeshSharma Yes I have done this already. But this invokes another issue, app.component is being called on the same tab for some other reason and it takes the already opened tab as new one if I clear the session storage manually. – Adnan Sheikh Jul 03 '19 at 10:49
  • How about adding an canActivate Guard and then check if the sessionStorage exists? If it exists do not load the component. @AdnanSheikh – Gopesh Sharma Jul 03 '19 at 10:58
  • @GopeshSharma doing this will create problem for the user loading the application for first time as there will be no sessionStorage for the first time. – Adnan Sheikh Jul 03 '19 at 11:14
  • @AdnanSheikh That's what you will check if the SessionStorage exists, if exists do not load the component, for the first time the sessionstorage does not exists to loading will not have a problem. – Gopesh Sharma Jul 03 '19 at 11:30
  • @GopeshSharma app.component.ts is a root component which does not require a route to load it. Is there any way I can put a canActivate Guard on this component? – Adnan Sheikh Jul 03 '19 at 12:15

1 Answers1

1

To prevent duplication you should use this code at application start.

window.addEventListener('beforeunload', function (event) {
    sessionStorage.removeItem('__lock');
});

if (sessionStorage.getItem('__lock')) {
    sessionStorage.clear();
    console.warn('Found a lock in session storage. The storage was cleared.');
}

sessionStorage.setItem('__lock', '1');
b4rtaz
  • 231
  • 2
  • 4
  • This won't work in iOS browsers because the event is not supported and the session storage is going the be cleared every time the page loads. You can use pagehide event instead. – punkgode Sep 13 '22 at 14:32