2013-12-02 4 views
85

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

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

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

Может ли кто-нибудь просмотреть мой вопрос, пожалуйста? Мой вопрос был отмечен как дублированный, но на самом деле связанный с ним вопрос был задан 2 года назад, но мои 3 года идут, а также этот вопрос более популярен, поэтому я считаю его отмеченным ошибкой. Может ли кто-нибудь исправить это или просто ответить, почему это произошло, пожалуйста? Благодарю.

ответ

73

Вы можете использовать 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'); 
}; 

Я испытал это в хроме, и далее, сафари, то есть 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/

+0

Насколько надежным является это решение? Поскольку это событие основано, есть ли вероятность пропустить событие? – vivek241

+0

На основании ответов здесь я создал библиотеку через localStorage и sessionStorage, чтобы упростить это. Итак, теперь вы просто вызываете storageManager.saveSyncedSessionData («данные», «ключ»); или storageManager.savePermanentData («данные», «ключ») и т. д. на основе того, что вам нужно.Полный код находится здесь: http://www.ebenmonney.com/blog/how-to-implement-remember-me-functionality-using-token-based-authentication-and-localstorage-in-a-web-application – adentum

+0

@ vivek241 Решение отлично подойдет для меня, когда размер файла JS меньше, а приведенный выше «сценарий решения» загружается как первый скрипт на странице. Когда мой JS-файл стал слишком большим, скажем 1000 или более строк, он внезапно прекратил работу и удалил мои файлы cookie и определенные данные локального хранилища. Я не уверен, что это надежное или кросс-браузерное решение, на которое можно положиться. Итак, переписал всю логику, чтобы решить проблему с помощью cookie. – webblover

46

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

От MDN Docs

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

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

+3

Хорошо, я понял, но как я могу очистить localStorage, когда все вкладки браузера закрыты? –

+0

Вы можете изменить файл cookie документов на 'path = '/'', заставив его очистить, когда окно браузера закрыто. Но для вкладок я понятия не имею прямо сейчас. –

+0

ok я буду копать глубже и сообщить вам, нашел ли я решение, подумал бы сейчас, что это невозможно)) –

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

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

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

-6

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

  1. В вашей первой странице JSP, OnLoad событие вызова сервлета (ajex вызов), чтобы настроить «window.title» и трекеру событий в сессии (всего целого переменная, которая должна быть установлена ​​как 0 в первый раз)
  2. Убедитесь, что ни одна из других страниц не задана как window.title
  3. Все страницы (включая первую страницу) добавляют скрипт java для проверки названия окна после загрузки страницы полный. если заголовок не найден, закройте текущую страницу/вкладку (не забудьте отменить функцию «window.unload», когда это произойдет)
  4. Установить страницу window.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"); 
} 
    } 
+0

Этот вопрос касается javascript, он не имеет ничего общего с javascript. – victorpacheco3107

0

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

Смежные вопросы