Store browser tab specific data

2020-06-09 07:14发布

问题:

I have a web application that store information about recently visited pages, let's call them A. When a user visits another page type, called B, I render a menu at the top with a button to point to the most recently visited A-page. The B-pages are accessible either through an A page or a B page and can by the user be considered a property of A.

This works fine but it becomes a problem when someone opens two tabs and when being on a B-page in tab 1 with a link to the A-page A1 they open a new tab and visits the A-page A2. When the user then refreshes the B-page in tab 1 the menu changes to A2. I'd like to be able to identify what tab is being used so that I can save A1 for tab 1 so that it doesn't change to A2.

When using one tab:

A1 -> B1 -> B2 (the menu points back to A1)

When using two tabs:

Time            | T1       | T2       | T3          
----------------+----------+----------+-------------
Tab 1:          | A1 -> B1 |          | [refresh B1]
Tab 2:          |          | A2 -> B3 |             
----------------+----------+----------+-------------
Menu points to: | A1    A1 | A2    A2 | A2

This confuses the users when they back in tab 1 comes to the user they were viewing in tab 2 (A2) instead of A1.

I'm afraid that it isn't possible to get the browser tab ID but someone might have any ideas of a workaround?

回答1:

Edit: The passage of time has rendered my original answer from 2012 incorrect. As bedrin points out, you may now use the Window.sessionStorage object:

The sessionStorage property allows you to access a session Storage object for the current origin. sessionStorage is similar to Window.localStorage, the only difference is while data stored in localStorage has no expiration set, data stored in sessionStorage gets cleared when the page session ends. A page session lasts for as long as the browser is open and survives over page reloads and restores. Opening a page in a new tab or window will cause a new session to be initiated, which differs from how session cookies work.

Original Answer (2012):

I am afraid this won't be possible in a portable way, as you have found out yourself it is not possible to retrieve something like a browser tab ID. The HTML standards are, as far as I am aware, completely unaware of tabs in browsers.

The only workaround I can think is would be this: Implement and mange tabs in your application. I have seen several business web applications that do this, but (imho) the user experience is quite bad.



回答2:

HTML5 sessionStorage solves this issue:

Sites can add data to the session storage, and it will be accessible to any page from the same site opened in that window.

It is supported by all modern browsers

Another approach is to use window.name property. It is tab/window specific and will remain unchanged on browser navigation. So you can store some king of tab id inside your window.name property



回答3:

So I've made one solution that seems to work pretty good NO IT DOESNT. See the last problem-bullet. I'm still hoping for better ideas so please let me know if you've got on!

Anyway; here's how I did it. Keep in mind that this is not a 100% fool-proof solution, if a user "misbehaves" and refreshes multiple tabs at the same time it can get confused:

base.html (which all pages inherits) ({{ A }} renders a variable from Django):

// This is executed right before leaving the page
window.onunload = function() {
    if( '{{ A }}' != null ) 
        var prev_A = '{{ A }}';
    else if (typeof previous_A != 'undefined') {
        var prev_A = previous_A;
    else 
        var prev_A = '';
    localStorage.setItem('a', prev_A);
};
// Remove the local storage as soon as you get to this page
localStorage.removeItem('a');

B_base.html (the base template of all B's. B_base.html also inherits base.html. I put this code to execute just before the code in base.html)

var previous_A = localStorage.getItem('a');

So basically what I get is that every page sets the localStorage 'a' when it leaves the page and deletes the localStorage 'a' as soon as it enters the page, except for the B-pages that first save 'a' as a local variable before deleting it.

Problems:

  • Opening links in multiple tabs at the same time will overwrite this variable and one tab will be without previous_A.
  • Closing an A tab without going anywhere, then open a new B-page directly will result in that the B-tab has the closed A's value in it's previous_A.
  • Open B-links in new tabs from A-page does not give them the link back... This is the dealbreaker.