cookie
2019年11月4日
10:49
· cookie是什么鬼
· 首先得先了解一下HTTP(超文本传输协议)
HTTP是一种无状态协议,即服务器不保留与客户交易(会话) 时的任何状态,同一个客户端的这次请求和上次请求没有对应关系,它并不知道这两个请求来自同一个客户端,为了解决这个问题, Web程序引入了cookie机制来维护状态。(但这种健忘症似的毛病,大大减轻了服务器记忆负担,从而保持较快的响应速度)
· 概念:
· cookie是一种会话跟踪技术,是浏览器提供的一种机制,是存储于访问者计算机中的一小块数据,可以由JavaScript对其进行操作(设置、读取、删除),其仅仅是浏览器实现的一种数据存储功能
会话:用户进入网站,开始浏览信息到关闭浏览器的过程,就称之为是一次会话,
会话跟踪技术:浏览器和服务器之间在进行多次请求间共享数据的过程,就称为会话跟踪技术
cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。
由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
· 应用场景
* 会话状态管理(如用户登录状态、购物车等)
* 个性化设置(保存用户设置的样式等)
* 浏览器行为跟踪(如跟踪分析用户行为等)
· 特性:
1. cookie可以实现跨页面全局变量
2. cookie可以跨越同域名下的多个网页,但不能跨域使用
3. cookie会随着HTTP请求发送给服务器
4. cookie会存储于访问者的计算机中
5. 同一个网站中所有页面共享一套cookie
6. 可以设置有效期限
7. 存储空间为4KB左右
拓展:
Microsoft指出InternetExplorer8增加cookie限制为每个域名50个,但IE7似乎也允许每个域名50个cookie,IE6为20个。
Firefox每个域名cookie限制为50个。
Opera每个域名cookie限制为30个。
Safari/Webkit貌似没有cookie限制。但是如果cookie很多,则会使 header大小超过服务器的处理的限制,会导致错误发生。
注意每个cookie文件大小不要超过4KB
· cookie的缺点
cookie可能被禁用
cookie与浏览器相关,不能互相访问
cookie可能被用户删除
cookie安全性不够高
cookie会随着HTTP请求发送给服务器
cookie存储空间很小(只有4KB左右)
cookie操作麻烦,没有方便的API
· 判断浏览器是否支持cookie
判断浏览器是否支持cookie //chrome放到远程服务器才能看到效果
if(navigator.cookieEnabled){
document.write("你的浏览器支持cookie")
}else{
document.write("你的浏览器不支持cookie")
}
· 创建cookie
创建并设置cookie过期时间 //IE在本地创建读取cookie, chrome本地创建可以,本地读取不行,远程都可以
document.cookie = "userName=刘亚朋&pwd=123456;expires=时间";
//封装的cookie
function setCookie($name, $value, $day) {
var data = $name + "=" + value; //拼凑数据 变量名=值
var myDate = new Date();
var mSecond = $day * 24 * 3600 * 1000;
myDate.setTime(myDate.getTime() + mSecond);//设置获得时间戳
data = data + "; expires=" + myDate.toGMTString();//变量名=值;expires=时间
document.cookie = data;//创建cookie
}
setCookie("刘亚朋", "123abc", 7);//调用函数创建cookie
· 操作cookie
每个cookie都是一个键/值对格式的字符串(key=value)
· 设置cookie:
document.cookie="user1=xh";
document.cookie="user2=xm";
如果要改变一个cookie的值,只能重新赋值
· 设置有效期:
var d=new Date();
d.setDate(d.getDate()+3); //按天数设置
document.cookie="user3=xd;expires="+d;
· 读取cookie:
var cookies = document.cookie;
只能够一次获取所有的cookie值
使用时必须自己解析这个字符串,来获取指定的cookie值
· 删除cookie:
cookie过期会自动消失
· 要删除一个cookie,可将其有效期设为一个过去的时间
var d=new Date();
d.setDate(d.getDate()-1);
document.cookie="user1=xh; expires="+d;
· 将指定cookie变量值设为空,并过期
· HTML5本地存储
概述:
本地存储将用户的一些偏好,用户当前的状态等等简单的信息,存储到本地电脑上。再次再访问的时候就可以直接调用。客户端的存储遵循"同源策略",不同站点之间的页面是无法互相读取对方存储的数据,而同一站点的不同页面之间是可以互相共享存储的数据,网页可以选择他们存储数据的有效期限。
本地存储cookie
cookie的设计初衷是给服务器端脚本用来存储少量数据的,该数据会在每次请求一个相关的url时传递到服务器中,不同浏览器对于本地cookie的数量都有一定的限制,不允许大量的使用cookie,并且每个cookie文件的大小不能大于4KB;
web存储
web存储最初作为HTML5的一部分被定义成api形式,但是后来被剥离出来作为独立的标准,目前该标准还在制定当中,但是其中一部分内容已经被所有的主流浏览器兼容。web存储标准描述的API包含localStorage和sessionStorage对象。web本地存储更加安全和快速,这些数据不会被保存在服务器上,只是用于用户请求网站数据,他可以存储大量的数据,而不影响网站的性能
· H5本地存储有 localStorage 与 sessionStorage 两种:
优点:
更大的存储空间,有5MB左右
不会随HTTP请求发送给服务器
有方便的API操作
移动端普及高
· localStorage 对象
为永久性保存数据,不会随着浏览器的关闭而消失。
按域名进行存储,可以在同域名下跨页面访问,不会和其他域名冲突。
按键值对存储:key/value
存储值
语法规则: localStorage.属性名=值;
读取
localStorage.属性名;
修改
与存储值一样,重新向该属性当中存储新的值即可替换原值。
· 操作:
localStorage.setItem(key , value) 保存或设置数据
如果key已经存在,则覆盖key对应的value
如果不存在则添加key与value
localStorage.getItem(key) 获取key对应的value
如果key不存在则返回null
localStorage.key(index) 获取指定下标位置的key
localStorage.length 获取数据条数(长度)
配合key(index)方法可以实现遍历localStorage数据的方法
localStorage.clear() 将同域名下的所有数据都清空
localStorage.removeItem('key') 删除某个键值对
sessionStorage 为临时性保存数据,当页面关闭就会消失
sessionStorage 不能跨页面访问,只局限在当前的标签页
sessionStorage 各种操作与 localStorage 一样
· sessionStorage对象与localStorage对象的使用方法完全一样,他们的区别在于存储的有效期和作用域不同。
localStorage存储的数据是永久性的,除非刻意的去删除,否则数据会一直保留在用户的电脑上永不过期
sessionStorage存储的数据是临时的,当该脚本所在的最顶层的窗口或浏览器关闭以后,数据就会被删除。
localStorage的作用域是限定在文档源(可以理解为在同一根目录下)级别的, (同一文档源即同源)同一文档源之间的不同页面可以共享localStorage数据,可以互相读取,设置覆盖修改。
sessionStorage的作用域也是限定在文档源级别的,不仅如此sessionStorage的作用域还被限定在窗口中,如果同源的文档渲染在不同的浏览器标签中,他们各自的sessionStorage数据无法共享
一个标签页面中的脚本是无法读取或者覆盖有另一个标签页脚本写入的数据,哪怕这两个标签页渲染的是同一个页面,运行的是同一个脚本也不行
· sessionStorage与localStorage的区别浓缩版:
localStorage为永久性保存数据,不会随着浏览器的关闭而消失, 其作用域是限定在文档源级别的, 可以在同域名下跨页面访问
sessionStorage为临时性保存数据,当页面关闭就会消失,其作用域限定在文档源级别,还被限定在窗口中,不能跨页面访问
· 离线存储
离线存储(浏览器缓存,客户端缓存)
传统的浏览器缓存,通过浏览器来判定需要缓存网页的哪些内容到本地,例如缓存·网页上的所有图片, css文件,js文件等等,当再次访问该页面时,浏览器会优先从浏览器缓存中读取缓存的内容,没有被缓存的内容才会向服务器请求相关内容。只有当缓存过期或者用户强制刷新缓存时才会重新向服务器请求内容。如果服务器页面内容发生了改变,但是浏览器缓存中的内容,还是旧页面内容,用户浏览的可能还会是旧页面的内容。
· H5离线缓存的特点
·离线浏览:用户可以在离线状态下浏览网站内容。
·更快的速度:因为数据被存储在本地,所以速度会更快.
·减轻服务器的负载:浏览器只会下载在服务器上发生改变的资源。
.h5离线缓存需要由开发人员自己定义要缓存的页面内容,那就需要有一个缓存文件清单,这个文件是一个manifest后缀名的文件,使用HTML5的离线存储就必须有这个文件,而且必须在服务器端做修改,使得. manifest后缀名的文件的mime类型为text/cache-manifest,典型的一个文件清单类似下面这个,一定是以CACHE MANIFEST开头的
-CACHE:指定你要浏览器进行离线存储的文件列表,一个文件一行
NETWORK:跟CACHE相反,指定浏览器一定要通过网络访问的文件列表
FALLBACK:如果通过网络访问失败了,就去访问紧跟着的那个在本地缓存好的文件
· 如何更新缓存
(1)更斯manifest文件
(2)通过javascript操作
(3)消除浏览器缓存
.给manifest添加或删除文件,都可更新缓存,如果我们更改了js,而没有新增或删除,前面例子中注释中的版本号,可以很好的用来更新manifest文件
.html5中引入了js操作离线缓存的方法,下面的js可以手动更新本地缓存.
.window.applicationCache.update() //应用储存更新
.如果用户清除了浏览器缓存(手动或用其他一些工具)都会重新下载文件。
· H5缓存的更新策略
HTML5的缓存更新策略是由manifest清单是否为最新版本来决定的,所以浏览器首先会根据HTT的缓存策略去探测manifest清单是否最新,如果最新(浏览器返回 304),则不会去下载清单里指定的缓存文件来更新离线存储,如果不是最新的(浏览器返回200) ,则会根据最新的manifest清单去重新下载指定的一系列文件,然后更新离线存储。
这里要注意,由于判断manifest清单是否最新是利用了HTTP的缓存策略的,所以可能出现你更改了manifest文件,但是离线存储却没有更新的情况,这可能是因为你的服务器为你的manifest清单文件设置了相应的缓存头, manifest清单文件还未过期,这是浏览器并没有真正向服务器发起请求确认manifest的新鲜度,而是直接使用了缓存的manifest件
另外一个需要注意的是,修改了一些文件以后想要让离线存储更新,就必须改动manifest清单文件。
JSON
目前 JavaScript 使用非常多的 json 格式
可以使用 JSON.stringify() 将 json对象 转为 json字符串
然后把 json字符串 存储在 cookie 或 localStorage 里面
读取出来以后使用 JSON.parse() 将 json字符串 转为 json对象
示例:
var jsonObj = {"name1":"jack","name2":"lily"};
localStorage.setItem("user",JSON.stringify(jsonObj)); // 存储
var jsonObj = JSON.parse(localStorage.getItem("user")); // 读取
二、应用缓存
除了http协议缓存,HTML5 提供一种应用程序缓存机制,使得基于web的应用程序可以离线运行。为了能够让用户在离线状态下继续访问 Web 应用,开发者需要提供一个 cache manifest 文件。这个文件中列出了所有需要在离线状态下使用的资源,浏览器会把这些资源缓存到本地。例如以下页面:
<!-- calender.html -->
<!DOCTYPE
HTML>
<html manifest="calender.manifest">
<head>
<title>calender</title>
<script src="calender.js"></script>
<link rel="stylesheet" href="calender.css">
</head>
<body>
<p>The time is: <output id="calender"></output></p>
</body>
</html>
其对应的 calender.manifest代码
CACHE MANIFEST
calender.html
calender.css
calender.js
cache manifest 格式遵循以下原则:
1. 首行必须是 CACHE MANIFEST。
2. 其后,每一行列出一个需要缓存的资源文件名。
3. 可根据需要列出在线访问的白名单。白名单中的所有资源不会被缓存,在使用时将直接在线访问。声明白名单使用 NETWORK:标识符。
4. 如果在白名单后还要补充需要缓存的资源,可以使用 CACHE:标识符。
5. 如果要声明某 URI 不能访问时的替补 URI,可以使用 FALLBACK:标识符。其后的每一行包含两个 URI,当第一个 URI 不可访问时,浏览器将尝试使用第二个 URI。
6. 注释要另起一行,以 # 号开头。
例如以下manifest文件:
CACHE MANIFEST
# 上一行是必须书写
images/sound-icon.png
images/background.png
NETWORK:
comm.cgi
# 下面是另一些需要缓存的资源,在这个示例中只有一个 css 文件。
CACHE:
style/default.css
FALLBACK:
/files/projects /projects
那么,如果使用了应用缓存,应该如何去更新呢?有以下两种方式
1、自动更新
浏览器除了在第一次访问 Web 应用时缓存资源外,只会在 cache manifest 文件本身发生变化时更新缓存。而 cache manifest 中的资源文件发生变化并不会触发更新。
2、手动更新
开发者也可以使用 window.applicationCache 的接口更新缓存。方法是检测 window.applicationCache.status 的值,如果是 UPDATEREADY,那么可以调用 window.applicationCache.update() 更新缓存。示范代码如下。
手动更新缓存代码:
if(window.applicationCache.status== window.applicationCache.UPDATEREADY)
{
window.applicationCache.update();
}
然而,有时候虽然应用缓存刷新了,但是还是不能看到最新的:那么有可能是使用了本地存储。常用的本地存储有DOM Storage和webSQL和indexDB三种
,细节可以参考这篇文章《HTML5 Storage Wars - localStorage vs. IndexedDB vs. Web SQL》,这里就不展开了,需要注意的是,若使用本地存储,想要清理缓存,除了清理本地存储文件外,还需要重启APP,以消除内存中的备份。