7

I'm debugging issues with running our web app in multiple browser tabs and have added a client log using log4javascript. I'm now trying to identify which log line is written by which browser tab, so I want to add a unique tab ID to each log line.

What this boils down to is that I need a way to identify that a browser tab is "new" and needs to receive a new tab ID. Tabs that have already received a tab ID should keep this ID.

But I have not found a way to store such an ID in a way that:

  • survives tab reloads
  • is always different between tabs
  • works within an iframe that is hosted in a different domain than the embedding page

Here is what I've tried:

  1. Store the tab ID in the session storage and generate a new ID if a tab's session storage does not yet contain such an ID.

    This works quite well in most cases. However, there are cases where a new tab starts out with a full copy of the session storage of the tab its been opened from. This seems to be the case when the new tab is being opened by clicking a hyperlink that references a new window target, or if the tab is duplicated. In this case we cannot differentiate between both tabs, so that both tabs end up using the same tab ID.

  2. Attach the tab ID to an HTML element using jQuery.data() and generate a new ID if the HTML element's data does not yet contain such an ID.

    This was stupid because it obviously does not survive tab reloads.

  3. Store the tab ID in the window.name of the iframe that contains our application and generate a new ID if the window.name does not yet contain such an ID.

    This doesn't work because the embedding application that generates the HTML iframe tag (and which we cannot change) sets the iframe name, so the tab ID is lost after each tab reload.

  4. Store the tab ID in the window.top.name and generate a new ID if the window.top.name does not yet contain such an ID.

    This doesn't work because we cannot set the window.top.name due to cross site security constraints (the embedding application is hosted in a different domain than the contents of our iframe).

  5. Embed yet another iframe within the iframe that contains our application, store the tab ID in the window.name of that iframe and generate a new ID if the inner iframe's window.name does not yet contain such an ID.

    This does not work because even though we do not explicitly set the inner iframe's name when opening it, the iframe's name is reset to the empty string upon tab reload. This is how we open the inner iframe:

    <iframe id="iframe2" src="index.jsp"></iframe>

I understand why the first four options didn't work. I'm not sure why the fifth option did not work as well and suspect that I might make a trivial mistake.

If not, I'm wondering if there is any other way that would allow me to identify the fact that a tab is new and hence in need of receiving a new tab ID.

Piers Uso Walter
  • 359
  • 4
  • 10
  • This answer may helps you: http://stackoverflow.com/questions/11896160/any-way-to-identify-browser-tab-in-javascript/36807854#36807854 – M Rostami Apr 23 '16 at 08:23

2 Answers2

3

Here is simple solution to have unique id inside single tab, which is persisted across tab reloads. For another opened tab id will be different.

The key here is using sessionStorage, which keeps data only per session (opened tab).

const idFromStorage = sessionStorage.getItem("ID_KEY");
if (idFromStorage) {
    return idFromStorage;
} else {
    const id = uuid(); // generate unique UUID
    sessionStorage.setItem("ID_KEY", id);
    return id;
}
Michael
  • 151
  • 1
  • 8
0

Why not try a combination: The page's hash + local storage. A page's hash is the part that comes after the # in the url. That part can be read and updated using location.hash. You can use that part in the url to append and persist your tab's id even across reloads.

You can then use localStorage to keep track of already used IDs. If a tab is loaded with no hash value, it generates one, saves it to localStorage and uses that value as id. If it comes with a hash (like after reloading), the page checks if that value is recorded or not. If not, it uses it. Otherwise, it generates another one.

Joseph
  • 117,725
  • 30
  • 181
  • 234