Skip to content
  • 兼容性: 兼容所有浏览器。

  • 容量: 存储容量比较少(4kb)。

  • 时间: 有存储时间限制(服务端可以设置)。

  • 稳定性: 不稳定, 清除浏览器历史记录或者垃圾清理时, 可以把 cookie 清除掉,浏览器无痕模下 会自动禁用cookie。

  • 与服务器是否有交互: 客户端向服务器发送请求时, 浏览器默认把cookie基于请求头发送给服务 器(跨域请求需要设置 withCredentials), 服务器可以在响应头中通过 Set-Cookie字段给 浏览器设置 cookie。

    • path:指定一个 url 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部,此目录的下级目录也满足匹配的条件(例如,如果 path=/docs,那么 /docs, /docs/Web/ 或 /docs/Web/HTTP 都满足匹配的条件)。

    • domain:指定 cookie 可以送达的主机名。假如没有指定,那么默认值为当前文档访问地址中 的主机部分(但是不包含子域名)。假如指定了域名,那么相当于各个子域名也包含在内了。

    • max-age:相对过期时间,秒数为 0 或 -1 将会使 cookie 直接过期,如果 expires 和 max-age 同时存在,max-age 优先级更高。

    • expires:绝对过期时间,时间格式为 GMT(UTC),对应方法为:new Date().toGMTString() 或 new Date().toUTCString()。如果没有设置,表示这是一个会话期 cookie,客户端被关 闭时,cookie 会被移除。

    • secure:一个带有安全属性的 cookie,只有在请求使用 SSL 和 HTTPS 协议的时候才会被发 送到服务器。非安全站点(http)不能在 cookie 中设置 secure 属性。

    • httponly:设置了 HttpOnly 属性的 cookie,在 JavaScript 中不能通过 Document.cookie、XMLHttpRequest 和 Request APIs 进行访问,以防范跨站脚本攻击。

    • sameSite:允许服务器设定 cookie 不随着跨域请求一起发送,可以在一定程度上防范跨站 请求伪造攻击声明。

      • lax,允许第三方站点 GET 请求中使用 cookie。

      • none:表示所有站点都可以发送,注意使用 none 时必须设置 secure 属性

      • strict:不允许第三方站发起的请求中使用该 cookie。

    Set-Cookie: 
    	<cookie-name>=<cookie-value>; 
    	Path=<path-value>;
    	Domain=<domain-value>; 
    	Max-Age=<max-age>; 
    	Expires=<Date>;
    	Secure;
    	HttpOnly;
    	SameSite=Lax
    js
    // 客户端要设置 withCredentials 为 true
    // 服务器要设置 Access-Control-Allow-Credentials 为 true
    res.setHeader('Set-Cookie', 
    	'key=val; path=path; domain=domain; max-age=max-age; expires=expires; secure'
    )
  • 浏览器设置 cookie

    javascript
    // 设置/更新cookie
    document.cookie = 'name=value'
    
    const time = Date.now() + 1000 * 60 * 60 * 24 * 365
    document.cookie = `
    	foo=bar;
    	max-age=60*60*24*365;
    	expires=${ (new Date(time)).toUTCString() }
    `
    
    // 获取所有cookie
    document.cookie
    
    // 删除cookie
    document.cookie = `
    	foo=bar;
    	max-age=0;
    `
    document.cookie = `
    	foo=bar;
    	expires=${ new Date().toUTCString() }
    `
  • cookie-store https://wicg.github.io/cookie-store/

javascript
	// 设置
	cookieStore.set('foo', 'bar') // 其他属性为默认值
	cookieStore.set({
	    foo: 'foo',
	    bar: 'bar'
	})
	
	// 获取
	cookieStore.get('foo').then(val => {
	  console.log(val)
	})
	cookieStore.get({foo: 'foo'}).then(val => {
	  console.log(val) // 等价于 cookieStore.get('foo')
	})
	cookieStore.getAll().then(val => {
	  console.log(val) // 获取所有 cookie
	})
	
	// 删除
	cookieStore.delete('foo').then(() => {})
	cookieStore.delete({foo: 'foo'}).then(() => {
	  // 等价于cookieStore.delete('age')
	})
	
	// 监听,成功 set 或 delete 时会触发回调,多次 set 相同的 cookie 也会触发。
	cookieStore.addEventListener('change', e => {
	  console.log(e)
	})

localStorage

  • 兼容性: H5 中新增的 API, 不兼容低版本浏览器。

  • 容量: 存储容量比较大(5Mb)

  • 时间: 没有存储时间限制, 是持久化存储,除非自己手动清除或把浏览器卸载了 。

  • 稳定性: 很稳定, 清除历史记录/清除垃圾/无痕模式下, 对 localStorage 的存储没有影响, 除非手动禁用localStorage。

  • 与服务器是否有交互: localStorage是单纯本地存储, 和服务器没有关系。

  • 浏览器设置 localStorage

    javascript
    // 获取
    localStorage.getItem(key)
    
    // 设置
    localStorage.setItem(key, val) // <=> localStorage[key] = val
    
    // 移除
    localStorage.removeItem(key) // <=> delete localStorage[key]
    
    // 清空
    localStorage.clear()
    
    // 监视 localStorage 对象的变化,相同域名下其中一个页面的 Storage 对象发生创建/更新/删除
    // 数据项时会触发其他页面的事件回调,如果设置相同的键值只会触发一次。
    window.addEventListener('storage', function(e) {
      	// e.key - 变化的 key
        // e.oldValue - 旧值
        // e.newValue - 新值
        // e.url - 哪个页面引起了 localStorage 对象改变
        // e.storageArea - localStorage 对象
    });
    
    Object.prototype.toString.call(localStorage) // output: '[object Storage]'
    
    // Question: localStorage存储的键值采用什么编码格式?
    // Answer: utf-16 DOMString格式
    
    // Question: key 占不占存储空间?
    // Answer: 占存储空间
    
    // Question: 5M的单位是什么?
    // Answer: 字符串的长度,即:键的长度 + 值的长度 <= 5 * 1024 * 1024
    
    // Question: 键和值的长度对读写性能的影响
    // Answer: 
    // 	读方面: 1 长度的 key 和 5 * 1024 * 1024 - 1 长度的 value 与
    //  5 * 1024 * 1024 - 1 长度的 key 和 1 长度的 value 差别有10倍左右,因此尽量保持 key 较短。
    // 	写方面:1 长度的 key 和 5 * 1024 * 1024 - 1 长度的 value 与
    //  5 * 1024 * 1024 - 1 长度的 key 和 1 长度的 value差别不大
    
    // Question: 计算localStorage的使用空间
    // Answer: Object.entries(localStorage).map(item => item.join('')).join('').length

sessionStorage

和 localStorage 操作语法一样,大部分特征也相同,sessionStorage 是会话存储,页面刷新 存储数据不会消失,页面一关闭(会话结束),存储数据自动清除。

全局变量(vuex / redux / 公共状态管理库)

  • 存储在运行内存中。

  • 页面刷新和关闭, 保存的数据都会释放。

本地数据库存储

  • IndexDB

  • WebSQL

  • ...

本地缓存存储

  • Cache Storage

  • Application Cache

本地离线存储

  • Manifest