How to prevent sessionStorage being inherited when using target="_blank"/window.open() to open a new window/tab?
Asked Answered
L

5

15

On a tab with url http://foo.com/ I set a sessionStorage item thus-

sessionStorage.bar="hello";

I then open a new window on any path on the same domain -

window.open("http://foo.com/any/path");

Then on the new window I find that -

sessionStorage.bar === "hello"

Is true. The exact same thing happens if I use a link with target="_blank" attribute to open the new window. The exact same thing also happens when a new tab is opened, and not a new window. Another thing to note is that this is only true for items set on sessionStorage before opening the new window. Adding or changing any item on sessionStorage in either windows after the new window is opened does not effect the other window in any way.

I thought that sessionStorage was supposed to be scoped to a single tab/window, but apparently sessionStorage is extended to new tabs and windows when they are opened from another window.

Is there a way to prevent this? I can probably test for existence of window.opener to detect such a case, but it would be much cleaner if it was possible to prevent it in the first place.

Thanks!

Lavatory answered 2/1, 2014 at 9:19 Comment(4)
sessionStorage is scoped to the session, hence the name. Doesn't matter the tab you have it on.Intersex
@JeremyMiller, thanks for your comment, could you please elaborate? How is the session then defined? MDN simply says that "Opening a page in a new tab or window will cause a new session to be initiated."Lavatory
hmmm... I must have been mistaken. Checking in detail now.Intersex
Found it. It's in the spec they link to, but it's a bit to type, so I'll post as an answer.Intersex
I
5

According to the Webstorage Specification, "When a new Document is created in a browsing context which has a top-level browsing context, the user agent must check to see if that top-level browsing context has a session storage area for that document's origin. If it does, then that is the Document's assigned session storage area."

So, my take on this is that if you close the tab, then open a new tab, it will be a new "session" per the specification. However, if the tab remains open and you then open a new tab, the top-level browsing context matches, so the sessionStorage is referenced.

Intersex answered 2/1, 2014 at 10:9 Comment(6)
Thanks! Do you have any suggestion as to how to override or bypass this behavior other than checking window.opener?Lavatory
Only by destroying the sessionStorage onLoad. What's your goal?Intersex
I can't destroy the sessionStorage, so I guess I would work around checking window.opener. Thanks again for your help and insights!Lavatory
This "cloning" behaviour seems specific to IE - Firefox and Chrome, at least, seem not to inherit sessionStorage from opening windows, and this post is the only thing I can find referring to sessionStorage inheritance. My take on that quote from the spec is, a "browsing context which has a top-level browsing context" refers to iframes. So an iframe with the same origin as the containing window gets the same sessionStorage - and exactly the same sessionStorage, i.e. changes made by one context will be seen by the other - unlike the "cloned" sessionStorage behaviour that only IE exhibits.Yuri
it's cloning for me on chrome 62 but not firefox 56Depolymerize
This might not be true.Barter
D
7

You can prevent a new tab or window from inheriting a copy of the original window's sessionStorage by setting the window.open windowFeatures parameter 'noopener' to true:

window.open('http://example.com', '_blank', 'noopener=true');

The parameter 'noreferrer' also works because, if set, the browser will omit the Referer header, as well as set noopener to true.

Mozilla documentation for window.open

Note: this parameter is not a solution when using window.open to open a URL in the same (i.e. current window, with the target set to '_self'). Although the reassigned window will not have a window.opener value, the session storage set by the prior URL may remain--at least if the new URL has the same domain.

Dogma answered 22/9, 2022 at 23:58 Comment(3)
Awesome solution! Hopefully it works in all browsers...?Ossian
I can vouch only for Firefox. When opening a URL in the same window, you can do this: let j = sessionStorage.length - 1; for (j; j >= 0; j--) { sessionStorage.removeItem(sessionStorage.key(j)); } window.open('http://www.example.com', '_self');Dogma
To follow up my last comment: This solution does not work in safari on iOS.Ossian
I
5

According to the Webstorage Specification, "When a new Document is created in a browsing context which has a top-level browsing context, the user agent must check to see if that top-level browsing context has a session storage area for that document's origin. If it does, then that is the Document's assigned session storage area."

So, my take on this is that if you close the tab, then open a new tab, it will be a new "session" per the specification. However, if the tab remains open and you then open a new tab, the top-level browsing context matches, so the sessionStorage is referenced.

Intersex answered 2/1, 2014 at 10:9 Comment(6)
Thanks! Do you have any suggestion as to how to override or bypass this behavior other than checking window.opener?Lavatory
Only by destroying the sessionStorage onLoad. What's your goal?Intersex
I can't destroy the sessionStorage, so I guess I would work around checking window.opener. Thanks again for your help and insights!Lavatory
This "cloning" behaviour seems specific to IE - Firefox and Chrome, at least, seem not to inherit sessionStorage from opening windows, and this post is the only thing I can find referring to sessionStorage inheritance. My take on that quote from the spec is, a "browsing context which has a top-level browsing context" refers to iframes. So an iframe with the same origin as the containing window gets the same sessionStorage - and exactly the same sessionStorage, i.e. changes made by one context will be seen by the other - unlike the "cloned" sessionStorage behaviour that only IE exhibits.Yuri
it's cloning for me on chrome 62 but not firefox 56Depolymerize
This might not be true.Barter
A
4

You can using this way:

    const a = document.createElement('a');
    a.href = "http://example.com/any/path";
    a.target = '_blank';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
Auvil answered 8/6, 2021 at 9:16 Comment(1)
This works like a charm in all browsers I have tested so far. :)Ossian
S
2

I solved this by temporary removing the session item while opening the new window.

sessionStorage.removeItem('bar');
window.open('http://example.com/any/path', '_blank');
sessionStorage.setItem('bar', 'hello');
Schwerin answered 13/6, 2021 at 14:35 Comment(0)
3
0

You can workaround the inheritance behavior by using a separate key per window (or if you have multiple keys, by applying some unique prefix to each key).

That begs the question of how to assign/retain a unique key per window. Well, SessionStorage is not empty when link opened in new tab in Internet Explorer shows that you can set the name of each window to some unique value, which is retained across reloads.

3d answered 20/8, 2019 at 2:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.