sessionStorage什么时候失效
最近在調試程序的時候無意間看到 cookie 的過期時間是 session,這個 session 表示的是什么時候過期?牽扯出來另一個存儲方案 sessionStorage 存儲的數據又是什么時候過期呢?
在查找相關資料的時候總會看到會話結束的時候 cookie 會被清除,當然 sessionStorage 內的數據也會在會話結束的時候被清除。
問題又來了會話是什么?會話什么時候會結束?
暫時拋開這些問題,看看 sessionStorage 是怎么使用,和之前的持久化存儲方案 cookie 有什么不同。
Storage
Storage 是 Web Storage API 的接口,localStorage 和 sessionStorage 都實現了這個接口,所以這兩個對象都有這個接口定義的屬性和方法。
-
Storage.length:只讀 存儲的數據項數量
-
Storage.key(n: number):返回存儲的第 n 個鍵名
-
Storage.getItem(key: string):返回 key 對應的值
-
Storage.setItem(key: string, value: string):存儲鍵和值,如果存在則更新
-
Storage.clear():清空存儲的所有數據
Storage 和 cookies
| 隨 HTTP 發送 | 是 | 否 | 否 |
| 最大數據量 | 4K | 5M | 5M |
| 失效時機 | 自己定義 或 隨著會話斷開失效 | 不清除不失效 | 隨著會話斷開失效 |
| 跨域限制 | 是 | 是 | 是 |
下面是 MDN 對 sessionStorage 的描述:
sessionStorage 屬性允許你訪問一個,對應當前源的 session Storage 對象。它與 localStorage 相似,不同之處在于 localStorage 里面存儲的數據沒有過期時間設置,而存儲在 sessionStorage 里面的數據在頁面會話結束時會被清除。
頁面會話在瀏覽器打開期間一直保持,并且重新加載或恢復頁面仍會保持原來的頁面會話。
在新標簽或窗口打開一個頁面時會復制頂級瀏覽會話的上下文作為新會話的上下文,這點和 session cookies 的運行方式不同。
打開多個相同的 URL 的 Tabs 頁面,會創建各自的 sessionStorage。
關閉對應瀏覽器窗口(Window)/ tab,會清除對應的 sessionStorage。
上面的內容引用自MDN Window.sessionStorage
對于以上的引用內容有如下問題:
什么是會話?
我理解會話是兩個實體之間的交流,交流是一個過程,無論從時間還是從內容都會表現成一個過程,一段時間。例如:從輸入賬戶密碼進入系統到退出系統就是一次會話的完成。TCP 的三次握手也創建了一次會話,TCP 四次揮手關閉連接則關閉了會話。
重新加載或恢復頁面,什么是恢復頁面?
恢復頁面就是瀏覽器窗口/tab 手動關閉或者意外關閉都是可以恢復的,恢復之后這個頁面的會話也會隨之恢復。前提是瀏覽器程序沒有被退出,如果程序被退出了無論是手動退出還是意外退出 session storage 和 session cookies 都會被清除。
在新標簽或窗口打開頁面,是在哪里打開的新窗口或頁面?復制頂級瀏覽會話,之后兩個會話就沒有聯系了嗎?
這里的打開新的標簽/窗口指的是在當前頁面觸發的動作導致新窗口/tab 的打開。復制而來的會話(session storage)和之前的會話沒有聯系。
和 session cookies 的運作方式不同,session cookies 的運作方式是什么?
session cookies 的運作方式不是復制,不同窗口/tab 同一域操作的 cookies 是同一個。
加載別的頁面是否算是會話結束?
不算會話結束,因為當前 tab 再次加載對應的 url 的時候還是可以訪問到對應的 sessionStorage。
為了解答上面的問題,我的嘗試如下:
在域 http://www.xx.com:80 下寫入數據sessionStorage.setItem('a', 1)
關閉當前 tab/窗口(保持瀏覽器程序沒有退出)
歷史記錄 -> 最近關閉的 tab -> 剛才關閉的 tab
sessionStorage.getItem('a')可以得到"1"
表明恢復的標簽和之前的標簽共享一個會話,因為它們是同一個標簽
當前標簽加載其它域名例如 http://jd.com
在回來 http://www.xx.com:80 這時候可以通過 sessionStorage.getItem('a')得到值"1"
表明同一個標簽同一個域會共享會話
在當前頁面通過鏈接 <a rel="opener" target='_blank' href='http://www.xx.com:80'>打開</a> 。(注意這里的ref屬性,一定要加上,缺省則不會有效)
在新開的 tab 下sessionStorage.getItem('a')可以得到得到值"1"
在新開的 tab 下sessionStorage.setItem('a', 2)
在原來的 tab 下sessionStorage.getItem('a')得到的還是 1
表明從當前域打開新的 tab/窗口會復制當前的會話作為新開頁面的會話,因為是復制出來的,兩個會話之間沒有關聯
關閉瀏覽器程序
再次打開瀏覽器,并且恢復 tab(不是新開 tab 打開同域頁面)
sessionStorage.getItem('a')得到的是 null 而不是"1"
表明關閉瀏覽器程序會結束會話
session cookies的失效
和 sessionStorage 的嘗試一致,對于 cookie 的過期時間是 session 也做了如上嘗試,得出的結論如下:
在瀏覽器關閉的情況下 session cookies 才會被清除,只是關閉相關 tab session cookies 還是存在,在此打開對應域的鏈接還是會看到相應cookies。
補充
參考Feature: Stop cloning sessionStorage for windows opened with noopener。
參考
MDN Window.sessionStorage
MDN Storage
HTTP 會話原理解釋與應用
sessionStorage 你可能會忽略的細節
實際中使用 Javascript 中 sessionStorage 的注意事項
總結
以上是生活随笔為你收集整理的sessionStorage什么时候失效的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx 使用try_files遇到的
- 下一篇: ESLint共享配置的两种方式eslin