phiên trình duyệtStorage. chia sẻ giữa các tab?


149

Tôi có một số giá trị trong trang web của mình mà tôi muốn xóa khi đóng trình duyệt. Tôi đã chọn sessionStorageđể lưu trữ những giá trị đó. Khi tab được đóng, chúng thực sự bị xóa và được giữ nếu người dùng nhấn f5; Nhưng nếu người dùng mở một số liên kết trong một tab khác, các giá trị này không có sẵn.

Làm cách nào tôi có thể chia sẻ sessionStoragegiá trị giữa tất cả các tab trình duyệt với ứng dụng của mình?

Trường hợp sử dụng: đặt một giá trị trong một số lưu trữ, giữ giá trị đó có thể truy cập được trong tất cả các tab của trình duyệt và xóa nó nếu tất cả các tab được đóng lại.

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

9
Thật kỳ lạ với tôi rằng điều này đã bị đóng như một bản sao. Đề cử để mở lại. Chủ đề khác là về "cách giao tiếp giữa nhiều tab", âm thanh khác nhau và cũng khác nhau, khi tôi bắt đầu đọc chủ đề khác đó.
KajMagnus

Có thể sử dụng cookie? Những hành vi như vậy theo mặc định? (nhưng thực sự - để có được và thiết lập hành động, họ sẽ yêu cầu triển khai thêm) developer.mozilla.org/en-US/docs/Web/API/Document/cookie
lingar

Câu trả lời:


132

Bạn có thể sử dụng localStorage và eventListener "lưu trữ" của nó để truyền dữ liệu sessionStorage từ tab này sang tab khác.

Mã này sẽ cần tồn tại trên TẤT CẢ các tab. Nó sẽ thực thi trước các tập lệnh khác của bạn.

// 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');
};

Tôi đã thử nghiệm điều này trong chrome, ff, safari, tức là 11, tức là 10, tức là 9

Phương pháp này "nên hoạt động trong IE8" nhưng tôi không thể kiểm tra vì IE của tôi bị sập mỗi lần tôi mở một tab .... bất kỳ tab nào ... trên bất kỳ trang web nào. (tốt ol IE) PS: rõ ràng bạn sẽ cần bao gồm một shim JSON nếu bạn cũng muốn hỗ trợ IE8. :)

Tín dụng vào bài viết đầy đủ này: http://blog.guya.net/2015/06/12/shaming-sessionst Storage-b between-abs-for-security-multi-tab-authentication /


2
Làm thế nào đáng tin cậy là giải pháp này? Vì nó là sự kiện dựa trên, có bất kỳ cơ hội bỏ lỡ một sự kiện?
vivek241

2
Dựa trên các câu trả lời ở đây, tôi đã tạo một thư viện qua localStorage và sessionStorage để đơn giản hóa việc này. Vì vậy, bây giờ bạn chỉ cần gọi StorageManager.saveSyncedSessionData ('data', 'key'); hoặc StorageManager.saveP PermanentData ('data', 'key');, vv dựa trên những gì bạn cần. Mã đầy đủ có tại đây: ebenmonney.com/blog/ từ
adentum

@ vivek241 Giải pháp hoạt động rất tốt đối với tôi khi kích thước tệp JS nhỏ hơn và "tập lệnh giải pháp" được đưa ra ở trên được tải dưới dạng tập lệnh đầu tiên trong trang. Khi tệp JS của tôi phát triển quá lớn, giả sử 1000 dòng trở lên, nó đột nhiên ngừng hoạt động và cũng loại bỏ cookie và dữ liệu localStorage cụ thể của tôi. Tôi không chắc đây là một giải pháp đáng tin cậy hoặc đa trình duyệt có thể dựa vào. Vì vậy, hãy viết lại tất cả logic để giải quyết vấn đề chỉ với cookie.
webblover

4
Không phải sự kiện sẽ được kích hoạt trong tất cả các tab mở trước đó?
Dtipson

3
Có vẻ như BroadcastChannelbây giờ là một công cụ tốt để làm điều này. developers.google.com/web/updates/2016/09/broadcastchannel
alexbea

71

Sử dụng sessionStoragecho điều này là không thể.

Từ Tài liệu MDN

Mở một trang trong một tab hoặc cửa sổ mới sẽ khiến một phiên mới được bắt đầu.

Điều đó có nghĩa là bạn không thể chia sẻ giữa các tab, vì điều này bạn nên sử dụng localStorage


8
Ok, tôi đã nhận nó, nhưng làm thế nào tôi có thể xóa localStorage khi tất cả các tab trình duyệt bị đóng?
Vladimir Gordienko

Bạn có thể thay đổi cookie tài liệu để path='/'buộc nó xóa khi cửa sổ trình duyệt bị đóng. Nhưng đối với các tab, tôi không có ý tưởng ngay bây giờ.
Henrik Andersson

ok tôi sẽ đào sâu hơn và cho bạn biết nếu tôi tìm thấy một giải pháp, hãy suy nghĩ ngay bây giờ những gì không thể))
Vladimir Gordienko

5
@Anmol có, nhưng tôi không thể cung cấp bất kỳ mã nào, nó đã có từ lâu. Đây là giải pháp xấu nhưng nó hoạt động hoàn hảo với tôi. Chìa khóa ở đây là giữ cho bộ đếm tabOpened trong bộ nhớ cục bộ và tăng nó khi tải trang nhưng giảm khi tải trang. Vì vậy, khi tải trang và tabOpen == 1 tab cuối cùng của nó và chúng tôi có thể xóa tất cả nội dung. Có một số điều nhỏ mà tôi cần phải xử lý nhưng không thể nhớ chính xác những gì. Hy vọng nó sẽ giúp bạn!
Vladimir Gordienko

1
@VladimirGordienko sẽ ra sao nếu sự kiện dỡ tải localStoragedữ liệu xảy ra do ai đó điều hướng đến một tên miền khác, trong cùng một tab. Dường như với tôi điều này sẽ xóa localStoragedữ liệu không chính xác - tab không bị đóng và nếu người đó điều hướng trở lại, họ sẽ muốn lại dữ liệu. Dù sao, đó là một cách tiếp cận thú vị, không nghĩ về điều đó: -)
KajMagnus

9
  1. Bạn chỉ có thể sử dụng localStoragevà ghi nhớ ngày đầu tiên được tạo session cookie. Khi localStorage"phiên" cũ hơn giá trị của cookie thì bạn có thể xóalocalStorage

    Nhược điểm của việc này là ai đó vẫn có thể đọc dữ liệu sau khi đóng trình duyệt, vì vậy đây không phải là giải pháp tốt nếu dữ liệu của bạn là riêng tư và tình cờ.

  2. Bạn có thể lưu trữ dữ liệu của mình localStoragetrong vài giây và thêm trình lắng nghe sự kiện cho một storagesự kiện. Bằng cách này, bạn sẽ biết khi bất kỳ tab nào viết một cái gì đó vào localStoragevà bạn có thể sao chép nội dung của nó vào sessionStorage, sau đó chỉ cần xóalocalStorage



0

Giải pháp của tôi để không có sessionStorage có thể chuyển qua các tab là tạo localProfile và tắt biến này. Nếu biến này được đặt nhưng các biến sessionStorage của tôi sẽ không được tiếp tục và khởi tạo lại chúng. Khi người dùng đăng xuất, cửa sổ sẽ đóng, phá hủy biến localStorage này


-14

Đây là một giải pháp để ngăn chặn phiên cắt giữa các tab trình duyệt cho một ứng dụng java. Điều này sẽ làm việc cho IE (JSP / Servlet)

  1. Trong trang JSP đầu tiên của bạn, sự kiện onload gọi một servlet (cuộc gọi ajex) để thiết lập "window.title" và trình theo dõi sự kiện trong phiên (chỉ một biến số nguyên được đặt thành 0 lần đầu tiên)
  2. Đảm bảo không có trang nào khác đặt window.title
  3. Tất cả các trang (bao gồm trang đầu tiên) thêm tập lệnh java để kiểm tra tiêu đề cửa sổ sau khi quá trình tải trang hoàn tất. nếu không tìm thấy tiêu đề thì hãy đóng trang / tab hiện tại (đảm bảo hoàn tác chức năng "window.unload" khi điều này xảy ra)
  4. Đặt trang window.onunload java script event (cho tất cả các trang) để chụp sự kiện làm mới trang, nếu một trang đã được làm mới, hãy gọi servlet để đặt lại trình theo dõi sự kiện.

1) trang đầu tiên

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 chung cho tất cả các trang

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 - ánh xạ servlet

<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) mã dịch vụ

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
Câu hỏi này là về javascript, nó không liên quan gì đến javascript.
victorpacheco3107

Đây là câu hỏi liên quan đến sessionStorage và localStorage
RR1112
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.