Appearance
cookie
兼容性: 兼容所有浏览器。
容量: 存储容量比较少(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=Laxjs// 客户端要设置 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