browser sessionStorage. share between tabs?

JavascriptCross BrowserSession Storage

Javascript Problem Overview


I have some values in my site which I want to clear when the browser is closed. I chose sessionStorage to store those values. When tab is closed they are indeed cleared, and kept if the user presses f5; But if the user opens some link in a different tab these values are unavailable.

How I can share sessionStorage values between all browser tabs with my application?

The use case: put a value in some storage, keep that value accessible in all browser tabs and clear it if all tabs are closed.

if (!sessionStorage.getItem(key)) {
    sessionStorage.setItem(key, defaultValue)
}

Javascript Solutions


Solution 1 - Javascript

You can use localStorage and its "storage" eventListener to transfer sessionStorage data from one tab to another.

This code would need to exist on ALL tabs. It should execute before your other scripts.

// transfers sessionStorage from one tab to another
var sessionStorage_transfer = function(event) {
  if(!event) { event = window.event; } // ie suq
  if(!event.newValue) return;          // do nothing if no value to work with
  if (event.key == 'getSessionStorage') {
    // another tab asked for the sessionStorage -> send it
    localStorage.setItem('sessionStorage', JSON.stringify(sessionStorage));
    // the other tab should now have it, so we're done with it.
    localStorage.removeItem('sessionStorage'); // <- could do short timeout as well.
  } else if (event.key == 'sessionStorage' && !sessionStorage.length) {
    // another tab sent data <- get it
    var data = JSON.parse(event.newValue);
    for (var key in data) {
      sessionStorage.setItem(key, data[key]);
    }
  }
};

// listen for changes to localStorage
if(window.addEventListener) {
  window.addEventListener("storage", sessionStorage_transfer, false);
} else {
  window.attachEvent("onstorage", sessionStorage_transfer);
};


// Ask other tabs for session storage (this is ONLY to trigger event)
if (!sessionStorage.length) {
  localStorage.setItem('getSessionStorage', 'foobar');
  localStorage.removeItem('getSessionStorage', 'foobar');
};

I tested this in chrome, ff, safari, ie 11, ie 10, ie9

This method "should work in IE8" but i could not test it as my IE was crashing every time i opened a tab.... any tab... on any website. (good ol IE) PS: you'll obviously need to include a JSON shim if you want IE8 support as well. :)

Credit goes to this full article: http://blog.guya.net/2015/06/12/sharing-sessionstorage-between-tabs-for-secure-multi-tab-authentication/

Solution 2 - Javascript

Using sessionStorage for this is not possible.

From the MDN Docs

> Opening a page in a new tab or window will cause a new session to be > initiated.

That means that you can't share between tabs, for this you should use localStorage

Solution 3 - Javascript

Actually looking at other areas, if you open with _blank it keeps the sessionStorage as long as you're opening the tab when the parent is open:

In this link, there's a good jsfiddle to test it. https://stackoverflow.com/questions/17297287/sessionstorage-on-new-window-isnt-empty-when-following-a-link-with-target-bl

Solution 4 - Javascript

  1. You can just use localStorage and remember the date it was first created in session cookie. When localStorage "session" is older than the value of cookie then you may clear the localStorage

    Cons of this is that someone can still read the data after the browser is closed so it's not a good solution if your data is private and confidental.

  2. You can store your data to localStorage for a couple of seconds and add event listener for a storage event. This way you will know when any of the tabs wrote something to the localStorage and you can copy its content to the sessionStorage, then just clear the localStorage

Solution 5 - Javascript

I find the only way to share sessionStorage between tabs is window.open:

  • window.open('./page2.html','') open page2 with a new tab
  • window.open('./page2.html','height=100, width=100') open page2 with a new tab in a new window.

Page2 can get a copy of sessionStorage from page1, but the two sessionStorage object is independent of each other.

Solution 6 - Javascript

My solution to not having sessionStorage transferable over tabs was to create a localProfile and bang off this variable. If this variable is set but my sessionStorage variables arent go ahead and reinitialize them. When user logs out window closes destroy this localStorage variable

Solution 7 - Javascript

If you have a small amount of data you can use instead of sessionStorage a session cookie which remains active until the user closes their browser or clears their cookies. And it also preserves its value among multiple tabs.

A code to set a cookie

document.cookie = "cookiename=value; path=/";

By omitting expires we set a session cookie.

And you retrieve it like this:

function getCookie(name) {
  var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
  if (match) return match[2];
}

var value = getCookie('cookiename');

Solution 8 - Javascript

Here is a solution to prevent session shearing between browser tabs for a java application. This will work for IE (JSP/Servlet)

  1. In your first JSP page, onload event call a servlet (ajex call) to setup a "window.title" and event tracker in the session(just a integer variable to be set as 0 for first time)
  2. Make sure none of the other pages set a window.title
  3. All pages (including the first page) add a java script to check the window title once the page load is complete. if the title is not found then close the current page/tab(make sure to undo the "window.unload" function when this occurs)
  4. Set page window.onunload java script event(for all pages) to capture the page refresh event, if a page has been refreshed call the servlet to reset the event tracker.

1)first page JS

BODY onload="javascript:initPageLoad()"

function initPageLoad() {
	var xmlhttp;

	if (window.XMLHttpRequest) {
		// code for IE7+, Firefox, Chrome, Opera, Safari
		xmlhttp = new XMLHttpRequest();
	} else {
		// code for IE6, IE5
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}

	xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {				              var serverResponse = xmlhttp.responseText;
		    top.document.title=serverResponse;
		}
	};
                xmlhttp.open("GET", 'data.do', true);
	xmlhttp.send();

}

2)common JS for all pages

window.onunload = function() {
	var xmlhttp;
	if (window.XMLHttpRequest) {
		// code for IE7+, Firefox, Chrome, Opera, Safari
		xmlhttp = new XMLHttpRequest();
	} else {
		// code for IE6, IE5
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {				
			var serverResponse = xmlhttp.responseText;				
		}
	};

	xmlhttp.open("GET", 'data.do?reset=true', true);
	xmlhttp.send();
}

var readyStateCheckInterval = setInterval(function() {
if (document.readyState === "complete") {
    init();
    clearInterval(readyStateCheckInterval);
}}, 10);
function init(){ 
  if(document.title==""){	
  window.onunload=function() {};
  window.open('', '_self', ''); window.close();
  }
 }

3)web.xml - servlet mapping

<servlet-mapping>
<servlet-name>myAction</servlet-name>
<url-pattern>/data.do</url-pattern>		
</servlet-mapping>  
<servlet>
<servlet-name>myAction</servlet-name>
<servlet-class>xx.xxx.MyAction</servlet-class>
</servlet>

4)servlet code

public class MyAction extends HttpServlet {
 public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws IOException {
	Integer sessionCount = (Integer) request.getSession().getAttribute(
			"sessionCount");
	PrintWriter out = response.getWriter();
	Boolean reset = Boolean.valueOf(request.getParameter("reset"));
	if (reset)
		sessionCount = new Integer(0);
	else {
		if (sessionCount == null || sessionCount == 0) {
			out.println("hello Title");
			sessionCount = new Integer(0);
		}
                          sessionCount++;
	}
	request.getSession().setAttribute("sessionCount", sessionCount);
	// Set standard HTTP/1.1 no-cache headers.
	response.setHeader("Cache-Control", "private, no-store, no-cache, must-                      revalidate");
	// Set standard HTTP/1.0 no-cache header.
	response.setHeader("Pragma", "no-cache");
} 
  }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVladimir GordienkoView Question on Stackoverflow
Solution 1 - JavascriptnawlbergsView Answer on Stackoverflow
Solution 2 - JavascriptHenrik AnderssonView Answer on Stackoverflow
Solution 3 - JavascriptDan ParkerView Answer on Stackoverflow
Solution 4 - JavascriptAdasskoView Answer on Stackoverflow
Solution 5 - JavascriptDreamoonView Answer on Stackoverflow
Solution 6 - Javascriptyardpenalty.comView Answer on Stackoverflow
Solution 7 - Javascriptmichal.jakubeczyView Answer on Stackoverflow
Solution 8 - JavascriptDTBView Answer on Stackoverflow