客户端存储方式的异同
客户端存储方式有:cookie、sessionStorage、localStorage、Web Storag等。
共同点: 都是保存在浏览器端,且有同源限制。
区别:
- cookie数据在浏览器和服务器间来回传递,和服务器端进行交互的,一般用于标识用户身份。而sessionStorage和localStorage用于浏览器缓存数据,不会自动把数据发给服务器,在本地保存。
- 由于Cookie是作为HTTP规范的一部分存在的,每次携带都会在HTTP头中,如果Cookie保存过多数据会带来性能问题,而WebStorage仅在客户端保存,不参与服务器的通信。一般浏览器不会修改cookie,但是会频繁操作cookie.
- cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
- 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,一般为5M左右。
- 数据有效期不同,sessionStorage仅在当前浏览器窗口关闭前有效,刷新页面后数据依旧存在,但关闭页面或关闭浏览器后就清除了,自然也就不可能持久保持;localStorage则是持久化的本地存储,除非被清除掉否则永久保存,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
- 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
- Web Storage 支持事件通知机制(storage事件),可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。(注:Web Storage实际上由两部分组成:sessionStorage与localStorage。)
如何用JavaScript
操作Cookie
、WebStorage
?
操作WebStorage
Cookie的操作需要自己封装getCookie,setCookie等,而Web Storage拥有setItem, getItem等方法可以使用,比如:
localStorage.setItem(“a”,”xxxxxx”); //设置
localStorage.getItem(“a”); //获取a的值
localStorage.removeItem(“a”); //删除a的值
document.cookie = “username=hyc”;
操作Cookie
在 JavaScript 中通过 document.cookie属性,你可以创建、维护和删除 Cookie
。创建 Cookie
时该属性等同于 Set-Cookie
消息头,而在读取 Cookie
时则等同于 Cookie
消息头。在创建一个 Cookie
时,你需要使用和 Set-Cookie
期望格式相同的字符串:1
document.cookie="name=Nicholas;domain=nczonline.net;path=/";
设置 document.cookie属性的值并不会删除存储在页面中的所有 Cookie
。它只简单的创建或修改字符串中指定的 Cookie
。下次发送一个请求到服务器时,通过 document.cookie设置的 Cookie
会和其它通过 Set-Cookie
消息头设置的 Cookie
一并发送至服务器。这些 Cookie
并没有什么明确的不同之处。要使用 JavaScript 提取 Cookie
的值,只需要从 document.cookie 中读取即可。返回的字符串与 Cookie
消息头中的字符串格式相同,所以多个 Cookie
会被分号和字符串分割。例如:name1=Greg; name2=Nicholas
鉴于此,你需要手工解析这个 Cookie
字符串来提取真实的 Cookie
数据。当前已有许多描述如何利用 JavaScript 来解析 Cookie
的资料,包括我的书,Professional JavaScript,所以在这我就不再说明。通常利用已存在的 JavaScript 库操作 Cookie
会更简单,如使用 YUI Cookie
utility 来处理 Cookie
,而不要手工重新创建这些算法。
通过访问 document.cookie返回的 Cookie
遵循发向服务器的 Cookie
一样的访问规则。要通过 JavaScript 访问 Cookie
,该页面和 Cookie
必须在相同的域中,有相同的 path,有相同的安全级别。
注意:一旦 Cookie
通过 JavaScript 设置后便不能提取它的选项,所以你将不能知道 domain,path,expires 日期或 secure 标记。
从JavaScript的角度看,Cookie
就是一些 字符串String类型 信息。Cookie
里面包含的信息并没有一个标准的格式,各个网站服务器的规范都可能不同,但一般会包括:所访问网站的域名(domain name),访问开始的时间,访问者的IP地址等客户端信息,访问者关于这个网站的一些设置等等。Cookie
一般包含一下几个属性:name(名字),value(值),domain(域),path(路径),expires(过期时间);其中,name和value是必须的,其他的会有默认值。domain的默认值是当前页面的域名,path的默认值是当前页的URL,expires的默认值是Session
(会话结束时清除Cookie
)。
- 写入
Cookie
写入Cookie
主要设置五个字段,内容、有效期、域名、路径、是否安全传输。Cookie
使用类似键值对的方式进行存储,比如“username=zhangshan”,只需将这个Cookie
赋值给document.Cookie
即可。名、值都要是标准的标识符,所以可以在使用前,用escape函数包裹,以免出错。document.cookie 有读和写两种形式,写形式代表添加Cookie
,且一次只能添加一条Cookice
,要添加多条则需要调用多次。处于安全性的考虑,Cookie
是具有不可跨域性的,只有与创建 Cookie
的页面在同一个目录或子目录下的网页才可以访问.把Cookie
设置为secure,那么它与服务器之间就通过HTTPS或者其它安全协议传递数据。c只保证 Cookie
与服务器之间的数据传输过程加密,而保存在本地的 Cookie
文件并不加密。如果想让本地Cookie
也加密,得自己加密数据。1
2
3document.cookie= "name=zhangsan;expires="+date.toGMTString();
//例如 "www.qq.com" 与 "sports.qq.com" 公用一个关联的域名"qq.com",我们如果想让 "sports.qq.com" 下的`Cookie`被 "www.qq.com" 访问,我们就需要用到 `Cookie` 的domain属性,并且需要把path属性设置为 "/"。
document.cookie= "name=zhangsan;domain=qq.com;secure";
- 读取
Cookie
读取Cookie
使用到document.Cookie
的读模式,返回的就是所有的Cookie
,中间用分号隔开。
1
2
3document.cookie= "name=zhangsan"; //写
document.cookie= "age=10"; //写
console.log(document.`Cookie`); //输出 name=zhangsan; age=10
- 删除、修改
Cookie
Cookie
并不提供删除、修改的方法,如果想修改某项Cookie
,只需添加一个同名Cookie
,新的值将覆盖旧的值。要删除Cookie
,只需将该Cookie
有效期设置到当前时间以前即可。
1
2
3
4
5
6
7document.cookie= "name=zhangsan";
document.cookie= "name=lisi"; //name被修改为lisi
var date = new Date();
//设置为前一毫秒(多前都可以)
date.setTime(date.getTime() - 1);
//删除name
document.cookie= "name=lisi;expires=" + date.toGMTString();
- 封装操作
Cookie
的方法
使用原生方法对Cookie
操作是有些麻烦的,我们可以将其封装起来,name代表键名,value代表值,不填则为读取名为name的值,option代表设置值如有效期等。其中有效期单位为天。
客户端存储 VS 客户端缓存
通过chrome://cache/
可以查看客户端缓存(浏览器文件缓存),文件缓存主要用来减少网络请求,提高页面加载速度的。包括你看的视频啊各种资源。除非手动永久删除,不然过期也还是在。
客户端存储就是一种存储技术,用来存取用户上网过程中的一些信息数据,和减少网络请求,提高页面加载速度没关系,就是存取状态的,数据可以用JS操作。比如:cookie用来标识用户有没有登陆;用户没有发出去的微博,也可以说是页面的状态数据,存在localStorage中,下次打开微博还在。缓存数据(数据库) !== 缓存
LocalStorage在浏览器多标签之间通信中的应用
localStorage 会触发一个事件。不论某个标签页在何时添加、修改或删除了 localStorage,都会对其余的所有标签触发事件,所有其它的标签页都能通过 window 对象监听到这个事件。这就意味着我们只要为 localStorage 赋值,通过监听事件,控制它的值,就能够跨浏览器标签通信了。使用localStorage.setItem(key,value);
添加内容,使用storage事件监听添加、修改、删除的动作。
注意quirks:Safari 在无痕模式下设置localstorge值时会抛出 QuotaExceededError 的异常。1
2
3window.addEventListener('storage', function (event) {
console.log(event.key, event.newValue);
});
例子:用户打开了两个标签页,在其中一个里执行了注销操作后返回另一个时,页面将重新载入,(如果可以的话)服务器端逻辑将把用户重定向到其它位置。这个检查只在当前标签页获得焦点时执行,这是因为用户可能在注销后立刻重新登录,这种情况下不应将其余标签页的状态全部设为已注销。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24var loggedOn;
// call when logged-in user changes or logs out
logonChanged();
window.addEventListener('storage', updateLogon);
window.addEventListener('focus', checkLogon);
function getUsernameOrNull () {
// return whether the user is logged on
}
function logonChanged () {
var uname = getUsernameOrNull();
loggedOn = uname;
localStorage.setItem('logged-on', uname);
}
function updateLogon (event) {
if (event.key === 'logged-on') {
loggedOn = event.newValue;
}
}
function checkLogon () {
var uname = getUsernameOrNull();
if (uname !== loggedOn) {
location.reload();
}
}
参考: