Браузер sessionStorage. делиться между вкладками?
У меня есть некоторые значения на моем сайте, которые я хочу очистить при закрытии браузера. Я выбрал sessionStorage
для хранения этих значений. Когда вкладка закрыта, они действительно очищаются и сохраняются, если пользователь нажимает клавишу f5; Но если пользователь открывает какую-либо ссылку на другой вкладке, эти значения недоступны.
Как я могу поделиться значениями sessionStorage
между всеми вкладками браузера с моим приложением?
Вариант использования: поместите значение в некоторое хранилище, оставьте его доступным на всех вкладках браузера и снимите его, если все вкладки закрыты.
if (!sessionStorage.getItem(key)) {
sessionStorage.setItem(key, defaultValue)
}
Ответы
Ответ 1
Вы можете использовать localStorage и его "хранилище" eventListener для передачи данных sessionStorage с одной вкладки на другую.
Этот код должен существовать на всех вкладках. Он должен выполняться перед вашими другими скриптами.
// 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');
};
Я тестировал это в chrome, ff, safari, т.е. 11, т.е. 10, ie9
Этот метод "должен работать в IE8", но я не мог его протестировать, так как мой IE разбивался каждый раз, когда я открывал вкладку... любую вкладку... на любом веб-сайте. (хороший ol IE) PS: вам, очевидно, нужно будет включить JSON-прокладку, если вы хотите поддерживать IE8.:)
Кредит относится к этой полной статье:
http://blog.guya.net/2015/06/12/sharing-sessionstorage-between-tabs-for-secure-multi-tab-authentication/
Ответ 2
Использование sessionStorage
для этого невозможно.
Из MDN Docs
Открытие страницы в новой вкладке или окне приведет к тому, что новый сеанс будет инициируется.
Это означает, что вы не можете делиться между вкладками, для этого вы должны использовать localStorage
Ответ 3
-
Вы можете просто использовать localStorage
и помнить дату, когда она была впервые создана в session cookie
. Когда localStorage
"session" старше значения cookie, вы можете очистить localStorage
Недостатки этого в том, что кто-то все еще может читать данные после закрытия браузера, поэтому он не является хорошим решением, если ваши данные являются конфиденциальными и конфиденциальными.
-
Вы можете сохранить свои данные на localStorage
в течение нескольких секунд и добавить прослушиватель событий для события storage
. Таким образом, вы узнаете, когда какая-либо вкладка что-то написала в localStorage
, и вы можете скопировать ее содержимое в sessionStorage
, а затем просто очистить localStorage
Ответ 4
Фактически, глядя на другие области, если вы открываете с помощью _blank, он сохраняет sessionStorage до тех пор, пока вы открываете вкладку, когда родитель открыт:
В этой ссылке есть хороший jsfiddle, чтобы проверить это.
sessionStorage в новом окне не пуст, когда вы следуете ссылке с target = "_blank"
Ответ 5
Мое решение не иметь sessionStorage, переносимого над вкладками, состояло в том, чтобы создать локальный файл и отключить эту переменную. Если эта переменная установлена, но мои переменные sessionStorage arent идут вперед и повторно инициализируют их. Когда пользователь выходит из окна закрытия, уничтожайте эту переменную localStorage
Ответ 6
Вот решение, чтобы предотвратить сдвиг сеанса между вкладками браузера для Java-приложения. Это будет работать для IE
(JSP/Servlet)
- На первой странице JSP событие onload вызывает сервлет (вызов ajex) для установки "window.title" и трекера событий в сеансе (только целочисленная переменная, которая будет установлена как 0 в первый раз).
- Убедитесь, что ни одна из других страниц не установила window.title
- Все страницы (включая первую страницу) добавляют java script, чтобы проверить заголовок окна после завершения загрузки страницы. если заголовок не найден, закройте текущую страницу/вкладку (не забудьте отменить функцию "window.unload", когда это произойдет)
- Установить страницу window.onunload java script событие (для всех страниц) для захвата события обновления страницы, если страница была обновлена, вызовите сервлет на reset отслеживатель событий.
1) первая страница 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) общий JS для всех страниц
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-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) код сервлета
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");
}
}