js中的数据存储
本文主要对 cookie、localStorage、sessionStorage、indexDB等知识点进行总结。
cookie
限制:
- 绑定在特定的域名下,当设定一个 cookie 后,再给创建它的域名发送请求都会包含这个 cookie 。确保存储在 cookie 中的信息只能让批准的接受者访问,无法被其他域访问。
- 每个域的 cookie 总数是有限的,不同浏览器之间各不相同。超过单个域名限制后再设 cookie 浏览器会清除以前设置的 cookie 。一个域下所有 cookie 的尺寸也有限制,大多数浏览器都有大约 4096B (加减1)的长度限制。如果尝试创建超过最大尺寸限制的 cookie 则该 cookie 会被丢掉。
构成:
- 名称:唯一确定 cookie 的名称,不区分大小写。cookie 的名称必须经过 URL 编码。
- 值:存储在 cookie 中的字符串值。值必须经过 URL 编码。
- 域:cookie 对于哪个域是有效的。
- 路径:对于指定域中的那个路径应该向服务器发送 cookie
- 失效时间:表示 cookie 何时应该被删除的时间戳即何时应该停止向服务器发送这个 cookie。默认情况下会话结束时即将所有的 cookie 删除。
- 安全标志:指定后 cookie 只有在使用 SSL 连接的时候才发送到服务器。
构成中的域、路径、失效时间、安全标志都是服务器给浏览器的指示(在 Set-Cookie 首部中以分号加空格分隔),并不会作为发送到服务器的 cookie 信息的一部分(只有名值对才会被发送)
javascript操作cookie
document.cookie
可以用来获取 cookie ,返回当前页面可用的所有 cookie 名值对字符串(分号加空格间隔)。也可以用于设置 cookie ,直接赋值操作并不会覆盖 cookie ,一般会被添加到现有的 cookie 集合中,除非设置的 cookie 名称已经存在。
Cookie 中的domain
- cookie 的作用域是当前域名domain和当前域名下的所有子域名,如域名设置为.baidu.com的cookie在域名 www.baidu.com 和 www.image.baidu.com 等子域名下都可以使用
- javascript设置cookie时,domain 只能为当前域名或者其父域名。如当前在 www.image.baidu.com 下,设置 cookie 的 domain 只能为 www.image.baidu.com 或者 .baidu.com,不能为 xxx.image.baidu.com 或 www.wenku.baidu.com
子cookie
绕开浏览器的单域名下 cookie 数限制。子cookie 是存放在单个 cookie 中的更小段的数据。最常见格式如下:name=name1=value1&name2=value2&name3=value3&name4=value4&name5=value5
http专有cookie
服务端可以设置 httpOnly:true
,带有该属性的 cookie 客户端无法获取。
缺陷
可以的情况下所有的 cookie 都会由浏览器作为请求头发送,在 cookie 中存储大量信息会影响到特定域的请求性能,cookie 信息越大完成对服务器请求的时间越长。cookie 的性质和其局限使其并不能作为存储大量信息的理想手段。
storage类型
- clear():删除所有值
- getItem(name):根据指定的名字 name 获取对应的值
- key(index):获得 index 位置处的值的名字
- removeItem(name):删除由 name 指定的名值对
- setItem(name,value):为指定的 name 设置一个对应的值
- length:存储在 storage 对象的名值对的数目
sessionStorage对象:存储特定于某个会话的数据(该数据只保存到浏览器关闭),可以跨越页面刷新而存在
globalStorage对象:跨越会话存储数据,使用 globalStrorage 是需要指定哪些域可以访问该数据,通过方括号标记使用属性来实现。访问和设置的是特定域名的存储空间(globalStorage对象不是Storage对象,globalStorage["xxx.xxx.xxx"]
才是),而且只能由来自该域名的页面访问(其他子域名都不行),并且对 globalStorage 空间的访问依据发起请求页面的域名、协议和端口来限制的(类似于同源策略)。如果不使用 removeItem 或者 delete 删除或用户为清除浏览器缓存,存储在 globalStorage 属性中的数据会一直保存在磁盘上。
localStorage对象:不能给 localStorage 指定任何访问规则,访问同一个 localStorage 页面必须来自同一个域名(子域名无效)、同一种协议、同一个端口。相当于 globalStorage[location.host]
。数据会一直保留直到通过 JavaScript 删除或者是用户清除浏览器缓存。
对 Storage 对象进行任何修改都会在文档上触发 storage 事件。这个事件的 event 对象有一下几种属性:
- domain:发生变化的存储空间的域名
- key:设置或删除的键名
- newValue:如果是设置值则是新值,如果是删除键则为 null
- oldValue:键被更改之前的值
IndexedDB
浏览器中保存结构化数据的一种数据库,操作完全是异步进行,大多数操作会以请求的方式进行,使用对象保存数据。
IndexedDB数据库只能有同源(相同协议、端口、域名)页面操作,不能跨域共享信息,每个来源的数据库占用的磁盘空间也有限制。
service worker
Service Workers 本质上充当 web应用程序与浏览器之间的代理服务器,也可以在网络可用时作为浏览器和网络间的代理,它们旨在(除其他之外)使得能够创建有效的离线体验,拦截网络请求并基于网络是否可用以及更新的资源是否驻留在服务器上来采取使用的动作,他们还允许访问通知和后台同步API。
目前通常用 service worker 来做缓存文件,提高首屏速度。
// index.js
if (navigator.serviceWorker) {
navigator.serviceWorker
.register('sw.js')
.then(function(registration) {
console.log('service worker 注册成功')
})
.catch(function(err) {
console.log('servcie worker 注册失败')
})
}
// sw.js
// 监听 `install` 事件,回调中缓存所需文件
self.addEventListener('install', e => {
e.waitUntil(
caches.open('my-cache').then(function(cache) {
return cache.addAll(['./index.html', './index.js'])
})
)
})
// 拦截所有请求事件
// 如果缓存中已经有请求的数据就直接用缓存,否则去请求数据
self.addEventListener('fetch', e => {
e.respondWith(
caches.match(e.request).then(function(response) {
if (response) {
return response
}
console.log('fetch source')
})
)
})
参考:前端进阶之道