[javascript] 브라우저 세션 탭 간 공유?

내 사이트에는 브라우저를 닫을 때 지우고 싶은 값이 있습니다. sessionStorage그 값을 저장 하기 로 선택했습니다 . 탭이 닫히면 실제로 지워지고 사용자가 f5를 누르면 유지됩니다. 그러나 사용자가 다른 탭에서 일부 링크를 열면이 값을 사용할 수 없습니다.

sessionStorage애플리케이션과 모든 브라우저 탭간에 값을 공유하려면 어떻게 해야합니까?

유스 케이스 : 일부 스토리지에 값을 넣고 모든 브라우저 탭에서 해당 값에 액세스 할 수 있도록 유지하고 모든 탭이 닫혀 있으면 값을 지우십시오.

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



답변

localStorage와 “storage”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');
};

나는 이것을 크롬, ff, 사파리, 즉 11, 10, ie9에서 테스트했습니다.

이 방법은 “IE8에서 작동해야합니다”. 그러나 탭을 열 때마다 IE가 충돌하여 웹 사이트에서 탭을 테스트 할 수 없습니다. PS : IE8 지원을 원한다면 분명히 JSON shim을 포함시켜야합니다. 🙂

크레딧은 전체 기사로 이동합니다 :
http://blog.guya.net/2015/06/12/sharing-sessionstorage-between-tabs-for-secure-multi-tab-authentication/


답변

사용 sessionStorage이를 위해 불가능합니다.

로부터 MDN 문서

새 탭이나 창에서 페이지를 열면 새 세션이 시작됩니다.

이는 탭간에 공유 할 수 없다는 것을 의미합니다. localStorage


답변

  1. localStorage에서 처음 작성된 날짜 만 사용 하고 기억할 수 있습니다 session cookie. 때 localStorage“세션”쿠키의 값보다 오래된 당신은 선택을 취소 할 수 있습니다localStorage

    이것의 단점은 브라우저를 닫은 후에도 누군가가 데이터를 읽을 수 있기 때문에 개인 정보와 자신감이 있다면 좋은 솔루션이 아닙니다.

  2. localStorage몇 초 동안 데이터를 저장 하고 storage이벤트에 대한 이벤트 리스너를 추가 할 수 있습니다 . 이렇게하면 탭 중 하나에 무언가를 썼을 때 localStorage그 내용을에 복사 할 수 있습니다 sessionStorage.localStorage


답변

실제로 다른 영역을 보면 _blank로 열면 부모가 열려있을 때 탭을 여는 한 sessionStorage가 유지됩니다.

이 링크에는 좋은 jsfiddle이 있습니다.
target = “_ blank”링크를 따라갈 때 새 창에서 sessionStorage가 비어 있지 않습니다


답변

탭을 통해 sessionStorage를 전송할 수없는 나의 해결책은 localProfile을 만들고이 변수를 사용하는 것입니다. 이 변수가 설정되었지만 sessionStorage 변수가 없으면 계속 초기화하십시오. 사용자가 로그 아웃 할 때이 localStorage 변수를 제거하십시오


답변

다음은 Java 응용 프로그램의 브라우저 탭 간 세션 전단을 방지하는 솔루션입니다. 이것은 IE (JSP / Servlet)에서 작동합니다

  1. 첫 번째 JSP 페이지에서 onload 이벤트는 서블릿 (ajex 호출)을 호출하여 세션에서 “window.title”및 이벤트 추적기를 설정합니다 (처음으로 0으로 설정되는 정수 변수)
  2. 다른 페이지가 창을 설정하지 않도록하십시오.
  3. 첫 페이지를 포함한 모든 페이지는 자바 스크립트를 추가하여 페이지로드가 완료되면 창 제목을 확인합니다. 제목을 찾을 수 없으면 현재 페이지 / 탭을 닫으십시오 (이 경우 “window.unload”기능을 취소하십시오)
  4. 페이지를 새로 고치려면 페이지 window.onloadload Java 스크립트 이벤트 (모든 페이지에 대해)를 설정하여 페이지 새로 고침 이벤트를 캡처하십시오. 페이지가 새로 고쳐지면 서블릿을 호출하여 이벤트 추적기를 재설정하십시오.

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


답변