在浏览器本地如何储存数据:Cookie和Web Storage

Posted by Mars at

浏览器端储存数据的几种方式:cookie,localStorage,sessionStorage,indexedDB

全面整理,包含以前的笔记。

一、Cookie

1. Cookie的作用

HTTP是无状态协议。Cookie的存在,是为了让服务器能识别连接过它的用户,从而在响应上针对性地采取一些友好措施。

比如一个购物网站,如果服务器无法识别客户是谁,是否曾经连接过服务器并进行某些操作。那么每次重新访问网站服务器,都需要重新登录,购物车里的东西也会被清零,因为服务器无法识别每次连接的客户。

Cookie是直接保存在浏览器中的一小段数据,在每次访问相同的域的时候,

2. Cookie的典型应用场景

Refer: 浅谈session,cookie,sessionStorage,localStorage的区别及应用场景

  1. 判断用户是否登陆过网站,以便下次登录时能够实现自动登录(或者记住密码);
  2. 保存上次登录的时间等信息;
  3. 保存上次查看的页面;
  4. 浏览计数。

3. Cookie的工作方式

当用户浏览某一个使用了Cookie的网站,则:

① 网站的服务器就生成一个该用户的识别码(唯一);

② 网站以此识别码为索引在服务器后端建立一个数据库项目;

③ 然后在给用户回复的HTTP响应报文中添加一个首部行:

Set-cookie:<唯一Cookie识别号>

④ 当客户收到响应报文,浏览器就在管理Cookie的文件中添加一行,其中包括这个服务器的主机名和它响应的识别码。

⑤ 当客户再次向这个服务器发送请求报文,浏览器就会自动地从管理Cookie的文件中抽出这个Cookie,并添加在请求报文的首部行中。

Cookie:

4. Cookie的结构、JS设置和体积限制

在打开页面的控制台输入document.cookie,可以查看某一个网站的cookie。结构如下:

某网站的Cookie:

“_ga=GA1.2.1788237449.1610895464; _ym_d=1610895465; _ym_uid=1610895465705583085; _gid=GA1.2.529167652.1619787501; _ym_visorc=w; _ym_isad=2; pixelRatio=1.75”

document.cookie 的值由 name=value 对组成,以 ; 分隔。每一个都是独立的 cookie。

通过document.cookie也可以设置当前域的cookie,Cookie的修改具有独立性: document.cookie = ‘cookieProperty=cookieContent;’ 这一设置,只会在cookie中添加(或修改)一个cookieProperty的值,不会覆盖全部的cookie。

通过document.cookie设置的cookie,都只能作用于当前域。

Cookie的体积大小不能超过4kB,条目数一般不能超过20条,具体与浏览器实现相关。

5. Cookie中的特殊字段

4.1 path

设置浏览器发送Cookie的url路径前缀。只有这个路径下的页面可以访问到这个Cookie。

一般设置 path=/;

这样这个域名下所有网页都可以访问到这个Cookie。 如果设置 path=/main 则只有main子目录的页面可以拿到Cookie

5.2 domain

设置可访问Cookie的域。

默认情况下,cookie是绑定到域的。也就是说,绑定到www.marswiz.com的 cookie,只能在这个域访问,即使是它的父级域marswiz.com也不行。

设置了 domain = site.com; 则 *.site.com 的所有域名都能拿到这个cookie(父域和子域)。

5.3 expires, max-age

expires是Cookie的到期日期,到期后Cookie被浏览器自动删除。

expires 需采用 GMT 时区格式,可以用 date.toUTCString 来获取它。

max-age是Cookie的存活时长,为一个数字,单位是秒。

expires和max-age二者设置其一就可以。

5.4 secure

规定这个Cookie只能被Https协议传输。

默认情况下,Cookie不区分协议,只区分域。

5.5 samesite

设置 samesite=strict 或 samesite 本身,含义是只在Cookie本身的域下向目标服务器发出请求,才会携带Cookie。、

其他域下,即使向相同的目标服务器发送请求,也不会携带Cookie。

这防止了一种叫做XSRF(Cross-Site Request Forgery 跨网站请求伪造)的攻击:

当用户已经在某一网站(site.com)完成登录认证,服务器返回了用户的Cookie并保存在浏览器中。默认情况下,只要从浏览器向site.com域发送请求,都会携带这个Cookie,服务器就会识别为认证的用户。

这时,如果用户访问了一个带有恶意请求代码(比如)的网站(evil.com),请求会带着Cookie发送到服务器,从而代表用户执行了恶意操作。

5.6 httpOnly(服务器端设置)

这个关键字在浏览器本地无法设置,只能在服务器端set-cookie的时候设置。

设置了httpOnly的Cookie,在浏览器中无法用JavaScript访问,也就是document.cookie看不到。(防止黑客获取到Cookie)

二、localStorage 与 sessionStorage

1. 概述

localStorage 与 sessionStorage 都用来在浏览器中保存键值对。(HTML5中提供)

localStorage 与 sessionStorage的键和值都必须是字符串,传入其他类型也会自动转换为字符串。

它们比Cookie的好处(区别)在哪?

  1. 不会像Cookie一样,随着每次请求一块发送到服务器;
  2. 保存的数据量更大,一般至少有2MB;
  3. 只能通过纯JavaScript操作,无法通过http等协议修改;
  4. Cookie是绑定到的(与协议和端口无关),而 localStorage 是绑定到的,也就是必须同一“协议+域名+端口”,才能访问同一 localStorage;
  5. sessionStorage只在当前标签页下有效,数据也只存在于当前浏览器标签页。

2. 应用场景

  • 保存用户在页面的输入内容,比如表单、文本等,防止刷新或重新访问后消失;
  • 快速响应:静态文件第一次请求后储存在localStorage,后续从localStorage直接读取,加快响应速度;
  • sessionStorage 的使用情况非常少。

3. localStorage 与 sessionStorage的通用方法

  • setItem(key, value) —— 存储键/值对。
  • getItem(key) —— 按照键获取值。
  • removeItem(key) —— 删除键及其对应的值。
  • clear() —— 删除所有数据。
  • key(index) —— 获取该索引下的键名。
  • length —— 存储的内容的长度。

4. localStorage 和 sessionStorage 的区别

  • localStorage用于本地长期储存,它的生命周期是永久的,除非用户手动删除或清空;
  • sessionStorage只在本次会话窗口(标签页)有效,窗口关闭就清空;
  • localStorage是绑定源的,“协议+域名+端口”相同的URI就可以访问,本地多个同源标签页共享同一localStorage;
  • sessionStorage是绑定标签页的,不同标签页即使同源也不共享sessionStorage,但是一个标签页内的iframe可以获取到该页面的sessionStorage。

5. 有关localStorage和sessionStorage的事件

每次更新localStorage和sessionStorage中的数据,storage事件就会发生,它的触发对象是所有能获取到该localStorage和sessionStorage的全局对象window

window.addEventListener('storage',(e)=>{
    console.log('storage changed.')
})

这个事件对象e具有如下属性:

  • key —— 发生更改的数据的 key(如果调用的是 .clear() 方法,则为 null)。
  • oldValue —— 旧值(如果是新增数据,则为 null)。
  • newValue —— 新值(如果是删除数据,则为 null)。
  • url —— 发生数据更新的文档的 url。
  • storageArea —— 发生数据更新的 localStorage 或 sessionStorage 对象。

所有能获取到更新的localStorage的window,都会被触发storage事件,这提供了一种跨标签页传递数据的方式:

比如:同时打开了两个同源的标签页,页面上同时监听了storage事件,回调函数是打印一个数据。

那么在一个标签页修改localStorage数据之后,另一个标签页会响应这个storage事件,同时也会打印这个数据。

三、indexedDB

1. 什么是indexedDB?

indexedDB是浏览器内置的一个数据库,它比localStorage更强大:

  1. 支持多种类型的键,储存多种JS类型的值;
  2. 更大的储存容量(一般至少250MB,甚至没有上限);
  3. 支撑事务(事务是一组同时成功或失败的操作),保证数据操作的可靠性;
  4. 支持键的范围查询(min,max等)、索引。

2. indexedDB 应用场景

在传统的浏览器-服务器页面应用有限,indexedDB主要应用于web离线应用。

3. indexedDB的使用方式

indexedDB也是绑定到源的,不同源的页面无法访问同一个indexedDB.

  • ① 要使用一个indexedDB数据库,需要先打开它;

let openRequest = indexedDB.open(name, version);

name —— 字符串,即数据库名称。

version —— 一个正整数版本,默认为 1。

  • ② indexedDB数据库中可创建对象库用来存储特定数据,通过事务进行数据操作;
  • ③ 通过键、范围或索引可以查询数据;

indexedDB使用的较少,具体使用方式参考:

IndexedDB 现代JS教程

previousPost nextPost
已经有 1000000 个小伙伴看完了这篇推文。