Làm cách nào để xóa một mục localStorage khi cửa sổ / tab trình duyệt bị đóng?


403

Trường hợp của tôi: localStorage với khóa + giá trị sẽ bị xóa khi đóng trình duyệt và không phải là một tab.

Vui lòng xem mã của tôi nếu nó phù hợp và những gì có thể được cải thiện:

//create localStorage key + value if not exist
if(localStorage){
   localStorage.myPageDataArr={"name"=>"Dan","lastname"=>"Bonny"}; 
}

//when browser closed - psedocode
$(window).unload(function(){
  localStorage.myPageDataArr=undefined;
});

32
Nếu bạn muốn xóa bộ nhớ cục bộ khi đóng trình duyệt, tôi sẽ hỏi lý do bạn sử dụng nó.
Dunhamzzz

16
Bạn có thể có cả đối tượng lưu trữ cục bộ và phiên - Tôi sẽ sử dụng sessionStorage cho các giá trị phiên. Btw, đặt giá trị thành không xác định sẽ không xóa nó hoặc xóa nó khỏi localStorage, nó chỉ đặt giá trị của nó thành không xác định.
kennebec

2
@kennebec - undefinedMặc dù vậy, cài đặt sẽ ghi đè lên mục được lưu trữ trước đó. Nhưng có, sử dụng .removeItem()là phù hợp hơn.
nnnnnn

2
chỉ sử dụng sessionStorage thay vì localStorage
Alberto Acuña

2
Sử dụng localStorage.clear(); nếu bạn muốn xóa toàn bộ lưu trữ.
Mamba đen

Câu trả lời:


802

nên được thực hiện như thế và không phải với toán tử xóa:

localStorage.removeItem(key);

1
Tại sao chúng ta không thể sử dụng toán tử xóa, chính xác? Từ các thử nghiệm của tôi, có vẻ như nó delete localStorage.keyhoạt động tốt như localStorage.removeItem(key). Nó có vẻ rõ ràng hơn đối với tôi để sử dụng xóa khi tôi đặt các biến của mình như thế localStorage.key = 1chứ không phải localStorage.setItem('key', 1).
Aust

6
Nếu nó hoạt động, bạn có thể sử dụng nó về mặt kỹ thuật. Nhưng xem xét removeItem được cung cấp như một hàm thành viên, có vẻ hợp lý khi sử dụng nó thay vì chạy vào hành vi có khả năng không xác định bằng cách sử dụng một toán tử riêng biệt.
kungphu

@kungphu hãy ghi nhớ một người luôn có thể (vô tình) làm localStorage.removeItem = null;, thực hiện localStorage.removeItem(key);một ý tưởng kém tiềm năng.
xiên 23/2/2016

31
Tôi không thấy đó là một kế hoạch hợp lý để lên kế hoạch cho. Thực tế là một ngôn ngữ cho phép mọi người thực hiện những việc phá hoại không có nghĩa là bạn nên áp dụng những cách sử dụng thư viện không chuẩn để bảo vệ việc sử dụng sai ngôn ngữ. Nếu bạn hoặc các nhà phát triển đồng nghiệp của bạn không hiểu sự khác biệt giữa gọi và gán, bạn có vấn đề lớn hơn nhiều so với cách loại bỏ các mục khỏi localStorage.
kungphu

3
@skeggse đây chính xác là lý do tại sao bạn nên viết localStorage.key = 1ngay từ đầu - để tránh loại tai nạn này
Jivan

114

Sử dụng với windowtừ khóa toàn cầu: -

 window.localStorage.removeItem('keyName');

6
Tại sao nên sử dụng cửa sổ Object? Đơn giản là localStorage.removeItem(key)hoạt động tốt.
Pardeep Jain


Giải pháp này có thực sự hiệu quả với IE 11 không? Xin đề nghị. Tôi đang gặp rắc rối này trong mã 5 góc.
Karan

95

Bạn có thể sử dụng beforeunloadsự kiện này trong JavaScript.

Sử dụng vanilla JavaScript, bạn có thể làm một cái gì đó như:

window.onbeforeunload = function() {
  localStorage.removeItem(key);
  return '';
};

Điều đó sẽ xóa khóa trước khi đóng cửa sổ / tab trình duyệt và nhắc bạn xác nhận hành động đóng cửa sổ / tab. Tôi hy vọng rằng giải quyết vấn đề của bạn.

LƯU Ý: onbeforeunloadPhương thức sẽ trả về một chuỗi.


Điều này thực sự hữu ích. Có thể tốt để chấp nhận câu trả lời (thậm chí sau tất cả thời gian này).
Richard Morgan

8
@dhsto VanillaJS là JavaScript đơn giản :) Xem tại đây: VanillaJS là gì? .
Bharat Khatri

1
Một vấn đề là điều này được gọi ngay cả khi bạn điều hướng trên cùng một trang, không chỉ khi tab được đóng, có thể không phải là mục đích. Lưu ý bên: trả lại không xác định từ onb Beforeunload sẽ vô hiệu hóa thông báo hiển thị khi dỡ tải.
Stan Bondi

Điều gì xảy ra nếu người dùng muốn ở lại trang và bạn đã xóa bộ nhớ cục bộ? Ngoài ra, giải pháp không hoạt động trên Chrome và IE11
oracleruiz

Tại sao không sử dụng sessionStorage sau đó?
Sachin Prasad

94

Bạn nên sử dụng sessionStorage thay thế nếu bạn muốn xóa khóa khi trình duyệt đóng.


3
Đây là câu trả lời tốt nhất; sessionStoragelà phương thuốc cho những gì người hỏi mô tả.
Benny

8
+1 để đề cập sessionStorage, nhưng Dự thảo của Biên tập viên W3C nói: 'Thời gian tồn tại của bối cảnh duyệt web có thể không liên quan đến thời gian tồn tại của chính quá trình tác nhân người dùng thực tế, vì tác nhân người dùng có thể hỗ trợ nối lại các phiên sau khi khởi động lại.'
Tamás

28
Vấn đề với 'sessionStorage' là nó không được lưu trữ khi bạn mở một tab mới, ví dụ với ctrl nhấp vào một liên kết. Tôi cần một lol lai LocalStorage / sessionStorage.
Edwin Stoteler

3
@EdwinStoteler Tôi cũng vậy. Tôi hơi bối rối khi họ nghĩ gì khi họ thiết kế nó theo cách này. Tôi thực sự cần quyền truy cập vào bộ nhớ trình duyệt chỉ trong bộ nhớ đã bị hủy khi trình duyệt đóng. Tôi muốn lưu trữ thông tin nhạy cảm theo cách có thể được truy cập trên toàn bộ tên miền, nhưng tôi không muốn thông tin đó đánh vào bất kỳ đĩa cứng nào.
BT

19

Hãy thử sử dụng

$(window).unload(function(){
  localStorage.clear();
});

Hy vọng điều này làm việc cho bạn


2
Bạn có muốn xóa localStorage hoàn chỉnh không? nếu vậy chỉ cần sử dụnglocalStorage.clear();
Rafael Marques

rõ ràng những gì tôi muốn trong câu hỏi - khóa chỉ xóa + giá trị
Yosef

12
Điều này sẽ làm sạch toàn bộ lưu trữ cục bộ. giải pháp xấu!
Emmy

12

Có một trường hợp sử dụng rất cụ thể trong đó mọi đề xuất sử dụng sessionStorage thay vì localStorage không thực sự hữu ích. Ca sử dụng sẽ đơn giản như có một cái gì đó được lưu trữ trong khi bạn có ít nhất một tab được mở, nhưng vô hiệu hóa nó nếu bạn đóng tab cuối cùng còn lại. Nếu bạn cần các giá trị của mình được lưu chéo và cửa sổ, sessionStorage không giúp bạn trừ khi bạn làm phức tạp cuộc sống của mình với người nghe, như tôi đã thử. Trong khi đó, localStorage sẽ hoàn hảo cho việc này, nhưng nó thực hiện công việc 'quá tốt', vì dữ liệu của bạn sẽ chờ ở đó ngay cả sau khi khởi động lại trình duyệt. Tôi đã kết thúc bằng cách sử dụng một mã tùy chỉnh và logic tận dụng lợi thế của cả hai.

Tôi muốn giải thích sau đó đưa ra mã. Đầu tiên lưu trữ những gì bạn cần trong localStorage, sau đó trong localStorage tạo một bộ đếm sẽ chứa số lượng tab mà bạn đã mở. Điều này sẽ được tăng lên mỗi khi trang tải và giảm mỗi lần tải trang. Bạn có thể chọn ở đây các sự kiện để sử dụng, tôi đề nghị 'tải' và 'dỡ tải'. Tại thời điểm bạn dỡ tải, bạn cần thực hiện các tác vụ dọn dẹp mà bạn muốn khi bộ đếm về 0, nghĩa là bạn đang đóng tab cuối cùng. Ở đây có phần khó khăn: Tôi chưa tìm thấy một cách đáng tin cậy và chung chung để nói sự khác biệt giữa tải lại trang hoặc điều hướng bên trong trang và việc đóng tab. Vì vậy, nếu dữ liệu bạn lưu trữ không phải là thứ bạn có thể xây dựng lại khi tải sau khi kiểm tra xem đây có phải là tab đầu tiên của bạn không, sau đó bạn không thể loại bỏ nó mỗi khi làm mới. Thay vào đó, bạn cần lưu trữ một cờ trong sessionStorage ở mỗi lần tải trước khi tăng bộ đếm tab. Trước khi lưu trữ giá trị này, bạn có thể thực hiện kiểm tra xem nó đã có giá trị chưa và nếu không, điều này có nghĩa là bạn đang tải vào phiên này lần đầu tiên, nghĩa là bạn có thể thực hiện dọn dẹp khi tải nếu điều này giá trị không được đặt và bộ đếm là 0.


Như một câu trả lời cho "tại sao không sử dụng sessionStorage?" cách tiếp cận, cũng từ w3schools.com/html/html5_webst Storage.asp : "window.sessionStorage - lưu trữ dữ liệu cho một phiên (dữ liệu bị mất khi đóng tab)". Vì vậy, câu trả lời chỉ có vậy. sessionStorage là vô dụng nếu bạn muốn một cái gì đó bền bỉ ngay cả trong usecase tôi đã mô tả.
Solthun 13/03/2015

3
Tôi nghĩ cách triển khai tốt nhất cho việc này sẽ là một dịch vụ Trình xem trình duyệt, về cơ bản kích hoạt các sự kiện mà các thành phần khác có thể nghe (ví dụ như mở trình duyệt, đóng trình duyệt, tải broswer, tải trình duyệt, v.v. và ẩn tất cả các chi tiết triển khai này bên trong nó Mỗi thành phần có thể quyết định những sự kiện nào cần xử lý để thực hiện công việc của mình. Câu hỏi duy nhất của tôi là điều gì sẽ xảy ra nếu nguồn điện bị cắt vào máy hoặc một cái gì đó, sau đó các thuộc tính này sẽ ở lại localStorage vào lần tới khi trình duyệt được mở ?
pQuestions123

11

sử dụng sessionStorage

Đối tượng sessionStorage bằng với đối tượng localStorage, ngoại trừ việc nó lưu trữ dữ liệu chỉ trong một phiên. Dữ liệu sẽ bị xóa khi người dùng đóng cửa sổ trình duyệt.

Ví dụ sau đây đếm số lần người dùng đã nhấp vào nút, trong phiên hiện tại:

Thí dụ

if (sessionStorage.clickcount) {
    sessionStorage.clickcount = Number(sessionStorage.clickcount) + 1;
} else {
    sessionStorage.clickcount = 1;
}
document.getElementById("result").innerHTML = "You have clicked the button " +
sessionStorage.clickcount + " time(s) in this session.";

1
Dữ liệu bị xóa trên tab trình duyệt đóng.
Kosmonaft

7
for (let i = 0; i < localStorage.length; i++) {
    if (localStorage.key(i).indexOf('the-name-to-delete') > -1) {
        arr.push(localStorage.key(i));
    }
}

for (let i = 0; i < arr.length; i++) {
    localStorage.removeItem(arr[i]);
}

5
localStorage.removeItem(key);  //item

localStorage.clear(); //all items

1
Khi trả lời một câu hỏi cũ, câu trả lời của bạn sẽ hữu ích hơn nhiều cho những người dùng StackOverflow khác nếu bạn đưa vào một số ngữ cảnh để giải thích cách trả lời của bạn, đặc biệt đối với một câu hỏi đã có câu trả lời được chấp nhận. Xem: Làm thế nào để tôi viết một câu trả lời tốt .
Tân

Có vẻ đủ rõ ràng với tôi
Giorgio Tempesta

4

Mặc dù, một số người dùng đã trả lời câu hỏi này rồi, tôi sẽ đưa ra một ví dụ về cài đặt ứng dụng để giải quyết vấn đề này.

Tôi gặp vấn đề tương tự. Tôi đang sử dụng mô-đun https://github.com/grevory/angular-local-st Storage trong ứng dụng angularjs của mình. Nếu bạn định cấu hình ứng dụng của mình như sau, nó sẽ lưu biến trong lưu trữ phiên thay vì lưu trữ cục bộ. Do đó, nếu bạn đóng trình duyệt hoặc đóng tab, bộ nhớ phiên sẽ tự động bị xóa. Bạn không cần phải làm bất cứ điều gì.

app.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
  .setPrefix('myApp')
  .setStorageType('sessionStorage')
});

Hy vọng nó sẽ giúp.


4

Có năm phương pháp để lựa chọn:

  • setItem (): Thêm khóa và giá trị vào localStorage
  • getItem (): Lấy một giá trị bằng khóa từ localStorage
  • removeItem (): Xóa một mục bằng khóa khỏi localStorage
  • clear (): Xóa tất cả localStorage
  • key (): Đã truyền một số để lấy khóa thứ n của localStorage

Bạn có thể sử dụng Clear (), phương thức này khi được gọi sẽ xóa toàn bộ lưu trữ của tất cả các bản ghi cho miền đó. Nó không nhận được bất kỳ tham số.

window.localStorage.clear();

3

Đây là một thử nghiệm đơn giản để xem bạn có hỗ trợ trình duyệt khi làm việc với bộ nhớ cục bộ hay không:

if(typeof(Storage)!=="undefined") {
  console.log("localStorage and sessionStorage support!");
  console.log("About to save:");
  console.log(localStorage);
  localStorage["somekey"] = 'hello';
  console.log("Key saved:");
  console.log(localStorage);
  localStorage.removeItem("somekey");  //<--- key deleted here
  console.log("key deleted:");
  console.log(localStorage);
  console.log("DONE ===");
} else {
  console.log("Sorry! No web storage support..");
}

Nó hoạt động với tôi như mong đợi (tôi sử dụng Google Chrome). Chuyển thể từ: http://www.w3schools.com/html/html5_webst Storage.asp .


3

Tôi không nghĩ rằng giải pháp được trình bày ở đây là chính xác 100% vì sự kiện window.onb Beforeunload được gọi không chỉ khi đóng trình duyệt / Tab (MÀ CẦN BẮT BUỘC), mà còn trên tất cả các sự kiện khác. (MIGHT KHÔNG ĐƯỢC YÊU CẦU)

Xem liên kết này để biết thêm thông tin về danh sách các sự kiện có thể kích hoạt window.onb Beforeunload: -

http://msdn.microsoft.com/en-us/l Library / ms536907 (VS85) .aspx


Bạn có thể đúng, nhưng những gì bạn đã đăng là một bình luận, không phải là một câu trả lời.
nnnnnn


3

Sau khi xem câu hỏi này 6 năm sau khi được hỏi, tôi thấy rằng vẫn chưa có câu trả lời đầy đủ cho câu hỏi này; cần đạt được tất cả những điều sau đây:

  • Xóa bộ nhớ cục bộ sau khi đóng trình duyệt (hoặc tất cả các tab của tên miền)
  • Giữ gìn bộ nhớ cục bộ trên các tab, nếu ít nhất một tab vẫn hoạt động
  • Bảo toàn bộ nhớ cục bộ khi tải lại một tab

Thực hiện đoạn javascript này khi bắt đầu mỗi lần tải trang để đạt được những điều trên:

((nm,tm) => {
    const
            l = localStorage,
            s = sessionStorage,
            tabid = s.getItem(tm) || (newid => s.setItem(tm, newid) || newid)((Math.random() * 1e8).toFixed()),
            update = set => {
                let cur = JSON.parse(l.getItem(nm) || '{}');
                if (set && typeof cur[tabid] == 'undefined' && !Object.values(cur).reduce((a, b) => a + b, 0)) {
                    l.clear();
                    cur = {};
                }
                cur[tabid] = set;
                l.setItem(nm, JSON.stringify(cur));
            };
    update(1);
    window.onbeforeunload = () => update(0);
})('tabs','tabid');

Chỉnh sửa: Ý tưởng cơ bản ở đây là như sau:

  1. Khi bắt đầu từ đầu, bộ lưu trữ phiên được gán một id ngẫu nhiên trong khóa được gọi là tabid
  2. Bộ lưu trữ cục bộ sau đó được thiết lập với một khóa gọi là tabschứa một đối tượng các khóa đótabid được đặt thành 1.
  3. Khi tab được tải, bộ nhớ cục bộ tabsđược cập nhật thành một đối tượng có chứatabid thành 0.
  4. Nếu tab được tải lại, lần đầu tiên nó được tải và tiếp tục lại. Vì khóa lưu trữ phiên tabidtồn tại và tabskhóa lưu trữ cục bộ cũng có khóa phụ làtabid bộ nhớ cục bộ sẽ không bị xóa.
  5. Khi trình duyệt được tải, tất cả bộ nhớ phiên sẽ bị xóa. Khi tiếp tục lưu trữ phiên tabidsẽ không còn tồn tại nữa và một cái mới tabidsẽ được tạo. Vì bộ nhớ cục bộ không có khóa phụ cho cái này tabid, cũng không có cái nào khác tabid(tất cả các phiên đã bị đóng), nên nó đã bị xóa.
  6. Khi một tab được tạo mới, một cái mới tabidđược tạo trong bộ lưu trữ phiên, nhưng vì có ít nhất một tabs[ tabid] tồn tại, bộ nhớ cục bộ không bị xóa

1
Tuy nhiên, nếu trình duyệt gặp sự cố, window.onbeforeunloadsẽ không được gọi và cục bộ tabs[tabid]sẽ không được đặt thành 0 => bộ nhớ cục bộ sẽ không bao giờ bị xóa nữa. Tôi nghĩ rằng một cơ quan giám sát sẽ phù hợp hơn trong trường hợp đó, thay vì viết 1 khi tải tab, bạn nên viết dấu thời gian hiện tại. Sau đó, trong phần rút gọn, bạn nên xác nhận độ trễ vì dấu thời gian đó không quá lớn hoặc thay bằng 0 nếu có. Bằng cách đó, bạn không phụ thuộc vào cuộc gọi thực tế của onbeforeunload. Các tab chỉ cần thiết lập lại cơ quan giám sát theo thời gian để duy trì sự tồn tại lưu trữ cục bộ.
xryl669

1

Đây là một câu hỏi cũ, nhưng dường như không có câu trả lời nào ở trên là hoàn hảo.

Trong trường hợp bạn muốn lưu trữ xác thực hoặc bất kỳ thông tin nhạy cảm nào bị phá hủy chỉ khi đóng trình duyệt, bạn có thể dựa vào sessionStoragelocalStoragecho thông báo qua thẻ chéo.

Về cơ bản, ý tưởng là:

  1. Bạn bootstrap từ không có tab nào trước đó được mở, do đó cả của bạn localStoragesessionStorageđều trống (nếu không, bạn có thể xóa localStorage). Bạn sẽ phải đăng ký một người nghe sự kiện tin nhắn trên localStorage.
  2. Người dùng xác thực / tạo thông tin nhạy cảm trên tab này (hoặc bất kỳ tab nào khác được mở trên miền của bạn).
  3. Bạn cập nhật sessionStorageđể lưu trữ thông tin nhạy cảm và sử dụng localStorageđể lưu trữ thông tin này, sau đó xóa thông tin đó (bạn không quan tâm đến thời gian ở đây, vì sự kiện đã được xếp hàng khi dữ liệu thay đổi). Bất kỳ tab nào khác được mở tại thời điểm đó sẽ được gọi lại vào sự kiện tin nhắn và sẽ cập nhật chúngsessionStorage với thông tin nhạy cảm.
  4. Nếu người dùng mở một tab mới trên tên miền của bạn, nó sessionStoragesẽ trống. Mã sẽ phải đặt một khóa trong localStorage(ví dụ req:). Bất kỳ (tất cả) tab khác sẽ được gọi lại trong sự kiện tin nhắn, xem phím đó và có thể trả lời với thông tin nhạy cảm từ sessionStorage(như trong 3), nếu chúng có như vậy.

Xin lưu ý rằng lược đồ này không phụ thuộc vào window.onbeforeunloadsự kiện dễ vỡ (vì trình duyệt có thể bị đóng / sập mà không có các sự kiện này được kích hoạt). Ngoài ra, thời gian thông tin nhạy cảm được lưu trữ trênlocalStorage rất nhỏ (vì bạn dựa vào phát hiện thay đổi của người chuyển đổi cho sự kiện tin nhắn trên tab chéo) nên không chắc là rò rỉ thông tin nhạy cảm như vậy trên ổ cứng của người dùng.

Đây là bản demo của khái niệm này: http://jsfiddle.net/oypdwxz7/2/


Cảm ơn bạn đã chỉnh sửa xryl669, bạn đã thực hiện một điểm tốt. Khi tôi đang nghĩ về điều này, có lẽ tốt nhất là sử dụng một nhân viên web chia sẻ? developer.mozilla.org/en-US/docs/Web/API/SharedWorker trong trường hợp hỗ trợ trình duyệt hiện tại không phải là vấn đề
Hacktisch

Có, bạn có thể sử dụng SharedWorker hoặc BroadcastChannel (hoặc localStorage như thế này), mặc dù hai cái đầu tiên không có sẵn trong Edge. Về cơ bản, bất kỳ phương pháp nào là tab chéo, cửa sổ chéo, sẽ hoạt động. Khó khăn là tìm một cái hoạt động ở mọi nơi với tối thiểu rắc rối.
xryl669

1

Không có cách nào để phát hiện đóng trình duyệt, vì vậy có lẽ bạn không thể xóa localStorage khi đóng trình duyệt nhưng có một cách khác để xử lý những thứ bạn có thể sử dụng sessionCookies vì ​​nó sẽ phá hủy sau khi đóng trình duyệt. Đây là dự án của tôi.


1

Bạn chỉ có thể sử dụng sessionStorage. Bởi vì sessionStorage cho phép xóa tất cả giá trị khóa khi cửa sổ trình duyệt sẽ bị đóng.

Xem ở đó: SessionStorage- MDN


-5

bạn có thể thử mã sau để xóa bộ nhớ cục bộ:

delete localStorage.myPageDataArr;

29
Đây không phải là cách đúng để xóa khóa localStorage. Bạn nên sử dụng localStorage.removeItem(key);để xóa một khóa.
MT.

1
Nên sử dụng localStorage.removeItem (key); không phải là từ khóa xóa.
Rob Evans

@MT. Tại sao không sử dụngdelete ? Tôi đã thử, và nó hoạt động. Có bất kỳ tác dụng phụ hoặc bất cứ điều gì mà chúng ta không nên sử dụng xóa? Cảm ơn bạn.
user1995781

2
@ user1995781 bằng cách sử dụng delete không phải là thực hành tốt nhất tronglocalStorage
justmyfreak

1
@justmyfreak Đó không phải là câu trả lời
alvitawa
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.