sessionStorage браузера. поделиться между вкладками? [дубликат]

этот вопрос уже есть ответ здесь:

У меня есть некоторые значения на моем сайте, которые я хочу очистить, когда браузер закрыт, я выбрал sessionStorage для хранения этих значений, ясно, когда вкладка закрыта и сохранить, если пользователь нажимает f5, но если пользователь открывает некоторую ссылку в другая вкладка это значения недоступны. Как я могу делиться значениями sessionStorage между всеми вкладками браузера с моим приложением?

вариант использования: поместите значение в некоторое хранилище, сохраните это значение на всех вкладках браузера и очистите его, если все вкладки закрыты.

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

6 ответов


вы можете использовать localStorage и его eventListener "storage" для передачи данных 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, ie 11, ie 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/


используя sessionStorage для этого невозможно.

С MDN Docs

открытие страницы в новой вкладке или окне вызовет новый сеанс инициированный.

это означает, что вы не можете делиться между вкладками, для этого вы должны использовать localStorage


  1. вы можете просто использовать localStorage и помните дату, когда он был впервые создан в session cookie. Когда localStorage "сеанс" старше значения cookie, тогда вы можете очистить localStorage

    минусы этого в том, что кто-то все еще может читать данные после закрытия браузера, поэтому это не хорошее решение, если ваши данные являются частными и конфиденциальными.

  2. вы можете хранить свои данные в localStorage в течение нескольких секунд и добавьте прослушиватель событий для storage событие. Таким образом, вы будете знать, когда любой из вкладок написал что-то в localStorage и вы можете скопировать его содержимое в папку sessionStorage, тогда просто очистите localStorage


фактически глядя на другие области, если вы открываете с _blank, он сохраняет sessionStorage до тех пор, пока вы открываете вкладку, когда родитель открыт:

в этой ссылке, есть хороший jsfiddle, чтобы проверить его. sessionStorage в новом окне не пуст, при переходе по ссылке с target= "_blank"


мое решение не иметь sessionStorage, передаваемого через вкладки, состояло в том, чтобы создать localProfile и отключить эту переменную. Если эта переменная установлена, но мои переменные sessionStorage не идут вперед и повторно инициализируют их. Когда пользователь выходит из окна закрывается уничтожить эту переменную localStorage


вот решение для предотвращения сеанса сдвига между вкладками браузера для приложения java. Это будет работать для IE (JSP / Servlet)

  1. на вашей первой странице JSP вызов события onload сервлет (вызов ajex) для настройки "окна.title " и event tracker в сеансе (только целочисленная переменная, которая будет установлена как 0 в первый раз)
  2. убедитесь, что ни одна из других страниц не установила окно.название
  3. все страницы (включая первую страницу) добавить скрипт java для проверки заголовок окна после завершения загрузки страницы. если заголовок не найден, закройте текущую страницу / вкладку(обязательно отмените "окно".функция "выгрузить", когда это происходит)
  4. установить окне страницы.onunload java script event (для всех страниц) для записи события обновления страницы, если страница была обновлена вызовите сервлет для сброса отслеживания событий.

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");
} 
  }