浅谈前端本地存储(cookie,sessionStorage,localStorage)

170 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

一、基本概念

1. cookie

Cookie 用于存储 web 页面的用户信息。可以记录用户的一些信息,操作,偏好设置等等。

2. sessionStorage

HTML5 标准中新加入的技术,主要用于保存会话场景中的数据到本地存储中。刷新页面时数据依然存在,但是当页面关闭后数据会清空。

3. localStorage

HTML5 标准中新加入的技术,主要用于持久化保存数据到本地存储中。除非被清除,否则永久保存。

二、基本使用

1. cookie

读取

allCookies = document.cookie;

// allCookies被赋值为一个字符串,该字符串包含所有的Cookie,每条cookie以"分号和空格(; )"分隔

写入

document.cookie = newCookie;

// 一次只能对一个cookie进行设置或更新
// 写入时是追加记录而不是覆盖原有记录
// 对于已存在相同的cookie名称的记录,将会更新cookie的值
  • 可选的cookie属性值可以跟在键值对后,用来具体化对cookie的设定/更新,使用分号以作分隔

  • cookie的值字符串可以用encodeURIComponent()来保证它不包含任何逗号、分号或空格(cookie值中禁止使用这些值).

     document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue));
    

获取指定名称的cookie值

function getCookie(name) { 
    // (^| )name=([^;]*)(;|$),match[0]为与整个正则表达式匹配的字符串,match[i]为正则表达式捕获数组相匹配的数组;
    var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
    if (arr != null) {
        console.log(arr);
        return unescape(arr[2]);
    }
    return null;
}
var cookieData = getCookie('token'); //cookie赋值给变量。

2. sessionStorage


// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');

// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');

// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');

// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();

3. localStorage


// 保存数据到 localStorage
localStorage.setItem('myCat', 'Tom');

// 从 localStorage 获取数据
let cat = localStorage.getItem('myCat');

// 从 localStorage 删除保存的数据
localStorage.removeItem('myCat');

// 移除所有localStorage
localStorage.clear();


三、 三者的区别

特性CookiesessionStoragelocalStorage
数据生命周期可设置失效时间,默认是关闭浏览器后失效仅在当前会话下有效,关闭页面或浏览器后被清除保存的数据没有过期时间,除非被清除,否则永久保存
数据共享Cookies的作用域大前提是相同浏览器的情况。数据在构建它们的窗口或标签内也可见,在相同标签页打开的多个iframe之间数据可以共享大前提是相同浏览器的情况。相同浏览器的不同页面间(同源页面)可以共享相同的localStorage
存放数据大小4K左右一般为5MB一般为5MB
服务器端通信每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题仅在客户端(即浏览器)中保存,不参与和服务器的通信仅在客户端(即浏览器)中保存,不参与服务器的通信
易用性需要程序员自己封装,源生的Cookie接口不友好源生接口可以接受,亦可再次封装来对Object和Array有更好的支持源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

四、一些特性的验证

1. 数据共享问题

这里总共有四个页面,两个是掘金的页面,两个是stackoverflow的页面 juejin.cn/post/701250…
juejin.cn/post/684490…
stackoverflow.com/questions/3…
stackoverflow.com/questions/1…

从两个网站中各取一个页面写入 sessionStorage和localStorage

image.png

image.png

image.png

image.png

image.png

image.png

可以发现,

  1. 相同浏览器的不同页面间(同源页面)可以共享相同的localStorage,而sessionStorage不可以。

  2. 不同源的页面无法共享localStorage,从stackoverflow写入的数据,掘金的网页无法读取到。

  3. localStorage的共享是共享同一份localStorage,类似于浅拷贝。

2. sessionStorage在子窗口中的共享问题

相同的文件,在不同浏览器中表现不一样。

文件

<!-- page1 -->

<body>
    <h1>这里是page1</h1>
    <a target="_blank" href="./page2.html">点击跳转到page2</a>
    <div id="res"></div>

    <script>
        window.sessionStorage.setItem("page1", "sessionStorage of page1")

        let res = document.getElementById("res")
        res.innerText = `page1:${window.sessionStorage.getItem("page1")}
        page2:${window.sessionStorage.getItem("page2")}
        page3:${window.sessionStorage.getItem("page3")}`
    </script>
</body>
<!-- page2 -->

<body>
    <h1>这里是page2</h1>
    <a target="_blank" href="./page3.html">点击跳转到page3</a>
    <div id="res"></div>

    <script>
        window.sessionStorage.setItem("page2", "sessionStorage of page2")

        let res = document.getElementById("res")
        res.innerText = `page1:${window.sessionStorage.getItem("page1")}
        page2:${window.sessionStorage.getItem("page2")}
        page3:${window.sessionStorage.getItem("page3")}`
    </script>
</body>
<!-- page3 -->

<body>
    <h1>这里是page3</h1>
    <!-- <a href="./page3.html"></a> -->
    <div id="res"></div>

    <script>
        window.sessionStorage.setItem("page3", "sessionStorage of page3")

        let res = document.getElementById("res")
        res.innerText = `page1:${window.sessionStorage.getItem("page1")}
        page2:${window.sessionStorage.getItem("page2")}
        page3:${window.sessionStorage.getItem("page3")}`
    </script>
</body>

谷歌浏览器:
页面间的sessionStorage不共享,每个页面只存储自己的sessionStorage
page1 : [p1]
page2 : [p2]
page3 : [p3]

360浏览器:
子页面可以共享父页面的sessionStorage
page1 : [p1]
page2 : [p1,p2]
page3 : [p1,p2,p3]

这一点不确定是因为浏览器的实现问题还是实验不规范,有了解的大佬可以评论区交流。

可以发现:

  1. sessionStorage的共享是共享副本,子页面保存一份副本到本地,类似于深拷贝。



参考文章:
cookie、localStorage和sessionStorage 三者之间的区别以及存储、获取、删除等使用方式

详说 Cookie, LocalStorage 与 SessionStorage

【面试】JavaScript的存储--Cookie、Session、localStorage、sessionStorage

你真的懂 sessionStorage 吗?

HTML5 localStorage security

What is the difference between localStorage, sessionStorage, session and cookies?

LocalStorage | MDN

Cookies的作用域