一、引子
自从H5的sessionStorage
和localStorage
出现后,cookie
的就业环境越来越艰难了。 理性的分析一波,cookie
为啥就业机会越来越少,以及还有没有用武之地。 本篇重点讲述浏览器cookie。
二、 cookie是啥
cookie 是存储于访问者的计算机中的变量。每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie。你可以使用 JavaScript 来创建和取回 cookie 的值。
关于cookie
的分类大体可以定义两种:
1. HTTP cookie(网络Cookie)
HTTP cookie 一个HTTP cookie的(网络Cookie,浏览器cookie)是一小片数据的一个服务器发送到用户的网络浏览器。浏览器可以存储它并将其与下一个请求一起发送回同一服务器。通常情况下,它用于判断两个请求是否来自同一个浏览器 - 例如,保持用户登录。它记住无状态 HTTP协议的有状态信息。
来源MDN
总结: 在http请求中发送过来的cookie, 能够直接在浏览器存储一些希望记录的状态或内容。
2. Document.cookie(浏览器cookie)
可以使用
Document.cookie
属性通过JavaScript创建新的cookie ,如果HttpOnly
没有设置标志,也可以从JavaScript访问现有的cookie。
**总结:**通过JavaScript对浏览器cookie进行增删改查操作。
三、 为什么需要浏览器缓存(cookie)
cookie翻译过来是“饼干”的意思,cookie在网络应用中到处存在. 由于http是无状态的协议,一旦客户端和服务器的数据交换完毕,就会断开连接,再次请求,会重新连接,这就说明服务器单从网络连接上是没有办法知道用户身份。因此每次新的用户请求时,给它颁发一个身份状态,下次访问,必须带上唯一身份状态,服务器根据不同状态,针对不同用户,做出不同的响应。
**总结:**http分辨不出当前客户端的状态,cookie就是存储在浏览器机器上的纯文本字符串,储存内容或状态信息,弥补http协议无状态的问题。
四、cookie在哪儿、怎么用?
栗子:
/**
* @params cookie对应全部字段内容
* @name 必需。规定 cookie 的名称。
* @value 必需。规定 cookie 的值。
* @expire 可选。规定 cookie 的有效期(默认即临时会话, 浏览器关闭即失效)。
* @path 可选。规定 cookie 的服务器路径。
* @domain 可选。规定 cookie 的域名。
* @secure 可选。规定是否通过安全的 HTTPS 连接来传输 cookie。
*/
document.cookie = 'userName=test123456';
document.cookie = 'userId=' + window.escape('45456da4344/*-+w2/,;3d1a3') + 'expires=' + new Date();
console.log(document.cookie);
// userName=test123456; userId=45456da4344/*-+w2/%2C%3B3d1a3expires=Tue Mar 26 2019 16:54:41 GMT+0800 (中国标准时间)
*注意1:*在cookie 的名或值中不能使用;
、,
、=
、空格
、。key值可控,但value值是不确定的,需要escape()
方法转为十六进制,此种方案还可以避免中文乱码的出现,解码时要用unescape()
;
*注意2:*获取指定的cookie值,如userName
需要处理字符串获取;
*注意3:*删除cookie值的方法是把有效时间修改为过去时间;
*注意4:*Chrome 浏览器无法设置本地静态cookie, 需要模拟在线环境;
五、 H5之后cookie的就业环境
-
H5新增了
sessionStorage
与localStorage
两种浏览器缓存,一种是会话级,一种硬盘级;他们的行业竞争力到底多强。 简单了解一下他们:-
localStorage
和sessionStorage
都是用来存储客户端临时信息的对象,存储在服务端,量大。附件1 -
他们均只能存储字符串类型的对象(虽然规范中可以存储其他原生类型的对象,但是目前为止没有浏览器对其进行实现)。
-
localStorage
生命周期是永久,这意味着除非手动清除localStorage
信息,否则这些信息将永远存在。 -
sessionStorage
生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage
存储的数据也就被清空了。 -
不同浏览器无法共享
localStorage
或sessionStorage
中的信息。相同浏览器的不同页面间可以共享相同的localStorage
(页面属于相同域名和端口),但是不同页面或标签页间无法共享sessionStorage
的信息。这里需要注意的是,页面及标签页仅指顶级窗口,如果一个标签页包含多个iframe
标签且他们属于同源页面,那么他们之间是可以共享sessionStorage
的。 -
可以通过
setItem()、getItem()、removeItem()、clear()、key()、valueOf()
方法进行增删改查; -
可以通过事件
storage
进行监听。
-
简单来说,H5的缓存使用简单粗暴,存储服务端相对安全,容量和内容足够大,能够对应不同情况,完爆同行cookie,cookie凭啥在挣扎。
-
cookie尚未失业的原因:
-
如果禁用
cookie
权限,那么sessionStorage
无法使用,原因在于sessionStorage
仍然是基于sessionId判断对应数据,只不过是存在了服务端;(你大爷还是你大爷); -
通过HTTP-cookie,可以使用PHP、Java等服务端语言操作cookie内容,并且能够设置
HttpOnly
防止客户端修改(说不安全的,逞强的说在secure
属性下,"我还有https"); -
cookie在与服务器通信时会附在
Request Headers
中发送到服务端,但H5缓存需要自己来根据需求封装; -
跨页面缓存,
session
能够应用在单页面项目中,但对于跨页面(跨标签页)的项目有些力不从心,而localStorage
虽然能够完成跨页面,但是需要手动删除,也需要额外处理;(粗糙的栗子附2)
-
-
cookie再就业会不会第二春: 先上结论,浏览器缓存中,H5正在逐步取代cookie,也建议使用H5的Web Storage;
-
抛开H5的优势不说,抛开安全性不谈,cookie的跨页面缓存虽然能够解决一定问题,但是并非无可替代,也正是因为跨页面缓存,会话级cookie是建立与整个浏览器进程的,现在的大部分浏览器即使在退出后进程仍然没有关闭,所以导致session Cookie的会话级存储被超预期的延长了,例如PC端的chrome浏览器,或手机端微信浏览器,需要特别注意。
-
关于cookie无法写入的问题
-
在a.com写b.com的cookie无法写入;
-
非https的请求但加入了secure参数的cookie无法写入;
-
在Chrome浏览器下,a.com中缓存cookie
user
,设置secure与domain=.erp.com
时,b.com写入user
在domain=.erp.com
中cookie无法写入 解释:其实是Chrome的一种保护措施(Safari,Firefox 随便写),如果不存在这种保护措施,在b.com发起请求时,cookie会变成user=cookie_from_a_erp_com;user=cookie_from_b_erp_com
;保护措施下,会默认读取同名中的第一个cookie发送。也就是在b.com发送请求时扔发送a.com的user。(前提是非要头铁的用同名cookie且设置secure)
-
-
总结:
cookie已经不适合作为唯一身份标识应用于项目中,但其特殊的优势在特定需求或接受/保存非敏感信息跨页面通信、获取服务端特定状态时,往往能收获不错的效果。因此,虽然提倡使用H5的Web Storage,但是灵活的应用cookie或许也是解决问题不错的思路。
补充:
- 如何判断浏览器是否禁用了cookie
window.navigator.cookieEnabled
// 如果浏览器启用了cookie,该属性值为true。如果禁用了cookie,则值为false。
-
js对特殊字符/中文转码方法
escape()除了 ASCII 字母、数字和特定的符号外,对传进来的字符串全部进行转义编码,因此如果想对URL编码,最好不要使用此方法。而encodeURI() 用于编码整个URI,因为URI中的合法字符都不会被编码转换。encodeURIComponent方法在编码单个URIComponent(指请求参 数)应当是最常用的,它可以讲参数中的中文、特殊字符进行转义,而不会影响整个URL。
附1:
IE 9 > 4999995 + 5 = 5000000
firefox 22.0 > 5242875 + 5 = 5242880
chrome 28.0 > 2621435 + 5 = 2621440
safari 5.1 > 2621435 + 5 = 2621440
opera 12.15 > 5M (超出则会弹出允许请求更多空间的对话框)
附2:
// 登录页面添加缓存
window.document.cookie = 'userName=cookie';
window.sessionStorage.setItem('userName', 'session');
window.localStorage.setItem('userName', 'local');
// check页跨页面js获取缓存
this.cookieVal = document.cookie.split('=')[1];
this.sessionVal = window.sessionStorage.getItem('userName');
this.localVal = window.localStorage.getItem('userName');
// check页跨页面html查看
<p>我是cookie值: {{cookieVal || '空'}}</p>
<p>我是session值: {{sessionVal || '空'}}</p>
<p>我是local值: {{localVal || '空'}}</p>
引用: