브라우저 세션 탭 간 공유?


151

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

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

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

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

9
이것이 복제본으로 폐쇄 된 것이 이상합니다. 재개를 추천합니다. 다른 주제는 "여러 탭간에 통신하는 방법"에 관한 것인데, 다른 주제를 읽기 시작할 때 다르게 들리기도합니다.
KajMagnus

쿠키를 사용할 수 있습니까? 기본적으로 어떤 식으로 동작합니까? (그러나 실제로-조치를 취하고 설정하려면 추가 구현이 필요합니다) developer.mozilla.org/en-US/docs/Web/API/Document/cookie
lingar

답변:


132

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/


2
이 솔루션은 얼마나 신뢰할 수 있습니까? 이벤트 기반이기 때문에 이벤트가 누락 될 가능성이 있습니까?
vivek241

2
여기에 대한 답변을 바탕으로 localStorage 및 sessionStorage를 통해 라이브러리를 만들었습니다. 이제 storageManager.saveSyncedSessionData ( 'data', 'key'); 또는 storageManager.savePermanentData ( 'data', 'key'); 등 필요한 항목을 기준으로합니다. 전체 코드는 여기에 있습니다 : ebenmonney.com/blog/...
adentum

@ vivek241 JS 파일 크기가 작고 위에 제공된 "솔루션 스크립트"가 페이지에서 첫 번째 스크립트로로드 될 때이 솔루션이 효과적이었습니다. JS 파일이 1000 줄 이상으로 커지면 갑자기 작동이 멈추고 쿠키와 특정 localStorage 데이터도 제거되었습니다. 이것이 신뢰할 수 있거나 브라우저 간 솔루션인지 확실하지 않습니다. 따라서 쿠키만으로 문제를 해결하기 위해 모든 논리를 다시 작성했습니다.
webblover

4
이전에 열린 모든 탭에서 이벤트가 트리거되지 않습니까?
Dtipson

3
BroadcastChannel작업을 수행하는 데 유용한 도구 인 것 같습니다. developers.google.com/web/updates/2016/09/broadcastchannel
alexbea

71

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

로부터 MDN 문서

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

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


8
알았어.하지만 모든 브라우저 탭을 닫을 때 어떻게 localStorage를 지울 수 있습니까?
Vladimir Gordienko

path='/'브라우저 창이 닫힐 때 문서 쿠키 를 지우도록 강제로 문서 쿠키를 변경할 수 있습니다 . 그러나 탭의 경우 지금은 모릅니다.
Henrik Andersson

좋아, 내가 더 깊이 파고 해결책을 찾았다면 알려줄 것입니다, 지금 불가능한 것을 생각하십시오))
Vladimir Gordienko

5
@Anmol 예, 그러나 이미 코드를 제공 할 수는 없습니다. 이것은 못생긴 솔루션이지만 완벽하게 작동합니다. 핵심은 로컬 저장소에 tabsOpened 카운터를 유지하고 페이지로드시에는 늘리지 만 페이지 언로드에서는 줄이는 것입니다. 따라서 페이지가 언로드되고 tabsOpen == 1 일 때 마지막 탭이며 모든 내용을 지울 수 있습니다. 내가 처리해야 할 사소한 것들이 있었지만 정확히 무엇을 기억할 수 없었습니다. 그것이 당신을 도울 것입니다 바랍니다!
Vladimir Gordienko

1
@VladimirGordienko localStorage누군가가 동일한 탭에서 다른 도메인으로 이동 하여 데이터 를 삭제하는 언로드 이벤트가 발생 하면 어떻게됩니까? 나에게 이것은 localStorage데이터 를 잘못 삭제합니다 . 탭이 닫히지 않았고, 다시 탐색하면 데이터를 다시 원할 것입니다. 어쨌든, 그것은 흥미로운 접근법입니다, 그것을 생각하지 않았습니다
:-)

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

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

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



0

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


-14

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

3
이 질문은 자바 스크립트에 관한 것이며, 자바 스크립트와 관련이 없습니다.
victorpacheco3107

이 질문은 sessionStorage 및 localStorage에 대한 질문입니다.
RR1112
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.