共计 58 个字符,预计需要花费 1 分钟才能阅读完成。
cookie
第 1 节 Cookie 快速入门
第 2 节 Cookie_细节
第 3 节 Cookie 案例
第 4 节 JSP 改造 Cookie 案例
正文完
发表至: java
2019-09-14
共计 58 个字符,预计需要花费 1 分钟才能阅读完成。
共计 2485 个字符,预计需要花费 7 分钟才能阅读完成。
- cookie 没有显示的删除函数,可以设置 expire/max-age 过期时间,自动触发浏览器的删除机制。- 服务器通过设置响应头来设置客户端的 cookie,Set-Cookie: cookie- 名 =cookie 值。可以同时添加多个 Set-Cookie,从而设置多个 cookie 的值。- 不允许存储敏感信息(用户名,密码等),一定要存储,要设置 cookie 为 httponly,另外考虑使用 非对称加密
- 浏览器 中的 cookie 数量达到上限后,会删除旧的创建新的,删哪个由浏览器的策略决定
- cookie 通常与 session 一起使用。- 登录时,server 端存储 用户信息相关的 session。- server 端,生成的 sessionid 会放在 cookie 中,对应域名下就有了这个 cookie。- 以后会自动带这个 cookie,server 根据 id 找到 session,获取用户信息。
document.cookie="userId=828";
document.cookie="userName=hulk";
此时浏览器将会维护两个 cookie,分别为 userId 和 userName;相当于:document.addCookie("userId=828");
document.addCookie("userName=hulk");
如果要改变一个 cookie 的值,只需重新赋值,例如:document.cookie="userId=929";
var strCookie=document.cookie;
console.log(strCookie); //userId=828; userName=hulk
- 只能一次获取所有的 cookie 的值,而不能指定 cookie 名称来获得指定的值。- 如果在某个页面创建了一个 cookie,那么该页面所在目录中的其他页面也可以访问该 cookie。- 为了控制 cookie 可以访问的目录,需要使用 path 参数设置 cookie。document.cookie="userId=320; path=/shop"; 就表示当前 cookie 仅能在 shop 目录下使用。
常用的 cookie 操作及其函数实现:
function addCookie(name,value,expireHours){var exdate = new Date();
exdate.setTime(exdate.getTime() + expireHours * 60 * 60 * 1000);
document.cookie = name + "=" + escape(value) + ((expireHours == null) ? "":";expires=" + exdate.toUTCString());
}
toUTCString() 方法可根据世界时 (UTC) 把 Date 对象转换为字符串,并返回结果。
function getCookie(name){let arr, reg = new RegExp(`^| ${name} = [^;]*;|$`);
if (arr = document.cookie.match(reg)) return arr[2];
else return null;
}
cookie 的可选项:
expires/max-age: 设置过期时间。
domain 和 path:
secure 和 httponly:
- 问题:“www.qq.com”与“sports.qq.com”公用一个关联的域名”qq.com”,我们如果想让”sports.qq.com”下的 cookie 被“www.qq.com”访问:- 解答:我们就需要用到 cookie 的 domain 属性,并且需要把 path 属性设置为“/“。例:document.cookie =“username=Darren;path=/;domain=qq.com“- 问题:同域名的资源请求时,会默认带上本地的 cookie,如何优化?- 解答:将静态资源分组,分别放在不同的子域下(子域名请求时,是不会带上父级域名的 cookie 的)
共计 3700 个字符,预计需要花费 10 分钟才能阅读完成。
一个 Vue 单页应用,A、B、C 三个页面都引用了一个公用的时间选择器。用户在各自页面选择完时间后,A,B,C 页面互相切换时保存选择的时间,在关闭浏览器 tab 后,清除选择的时间,恢复初识值。一开始的想法是使用会话 cookie(不手动设置过期时间),但是会话 cookie 在关闭浏览器 tab 的时候不会被清除。所以决定研究下会话 cookie 何时清除。
HTTP 是一种无状态的协议,它不对请求和响应之间的通信状态进行保存,即无法根据之前的状态进行本次请求的处理。假如要求登录验证的 web 页面本身无法进行状态的管理,那么每次跳转新页面就要再次登录,或者要在请求报文中附加参数来管理登录状态。无状态协议有它的优点,由于不必保存状态,可以减少服务器的 CPU 及内存资源。为了保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了 cookie。
cookie 技术通过在请求和响应报文中写入 cookie 信息来控制客户端的状态。cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 cookie 值后发送出去。
服务端发现客户端发送过来的 cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
// 属性之间由一个分号和一个空格隔开
document.cookie = 'name=value[; expires=date][; domain=domain][; path=path][; secure]'
// 设置多个 cookie
document.cookie = 'name=irene; domain=www.baidu.com';
document.cookie = 'age=18; path=/welcome';
document.cookie 一次只能设置一条 cookie,如果需要设置多条,需要多次设置。客户端可以设置的属性有:expires、max-age、domain、path、secure(https 协议下才能设置成功),不能设置 HttpOnly。
Set-Cookie: name=value[; expires=date][; domain=domain][; path=path][; secure]
// 设置多个 cookie
Set-Cookie: name=irene; domain=www.baidu.com;
Set-Cookie: age=18; path=/welcome;
一个 Set-Cookie 只能设置一条 cookie,如果需要设置多条,需要多次使用 Set-Cookie。cookie 除了设置名称和值之外,还可以设置其他的属性。服务端可以设置的属性有:expires、max-age、domain、path、secure、HttpOnly 等。
设置 cookie 的失效时间。expires 的值是一个时间点(cookie 失效时刻 = expires),max-age 的值是秒数(cookie 失效时刻 = 创建时刻 + max-age)。expires 是 http/1.0 协议中的选项,在新的 http/1.1 协议中 expires 已经由 max-age 选项代替。如果两者同时存在,max-age 的优先级高于 expires。max-age 有两种可能值:小于等于 0:有效期为能表示的最早时间;大于 0:有效期为当前时间 + max-age。
// expires
document.cookie='name=irene; expires=Wed, 13 Jun 2019 10:28:27 GMT'
// max-age > 0
document.cookie='name=irene; max-age=3600'
// max-age <= 0
document.cookie='name=irene; max-age=0'
注意:一旦 cookie 从服务器端发送至客户端,服务器端就不存在可以显式删除 cookie 的方法。但可通过覆盖 cookie,实现对客户端 cookie 的删除操作。
Domain 设置域名,默认是当前域名。path 设置路径,默认是当前目录。domain 和 path 一起限制了哪些请求可以带上该 cookie。比如上面第二个的 cookie,若请求的 URL 的域名是 juejin.com 或 xxx.juejin.com,并且 URL 的路径是 / 或 子路径 ‘/home’,则浏览器会将此 cookie 添加到该请求的 cookie 头部中。
// 在 https://juejin.im/welcome/frontend 设置如下 cookie,则浏览器 Cookie 面板显示的 domain=juejin.im,path=/welcome
document.cookie = 'name=irene'
// 在 https://juejin.im/welcome/frontend 设置如下 cookie,则浏览器 Cookie 面板显示的 domain=.juejin.im(有前缀.),document.cookie = 'name=irene; domain=juejin.im; path=/welcome/frontend'
// 关于 domain 有无前缀点可参考 http://www.it1352.com/548425.html
当设置了 HttpOnly,浏览器就不会将该 cookie 添加到非 HTTP 请求的头部。
设置 cookie 是否能通过 js 去访问(读取、修改、删除等)。默认情况下,cookie 不会带 HttpOnly 选项,所以客户端是可以通过 js 代码去访问这个 cookie 的。当 cookie 带 HttpOnly 选项时,客户端则无法通过 js 代码去访问这个 cookie。主要目的是为防止跨站脚本攻击对 cookie 的信息窃取。HttpOnly 只能从服务端设置,不能通过客户端设置。
设置仅在 HTTPS 安全连接时,才可以发送 cookie。
一个字符串(str)匹配(domain-matches)一个给定的域名字符串(domain str)至少需要满足以下条件中的一个:
或者同时满足以下条件:
2.1 domain str 是 str 的后缀。
2.2 str 中最后一个不包含在 domain str 中的字符是点(.)。
domain str = google.com; str = map.googole.com => 符合
domain str = google.com; str = map.mgoogle.com => 最后一个不包含在 domain str 中的字符是 m,不符合
2.3 str 必须是一个域名,而不是 IP 地址。
一个请求路径(request-path)匹配(path-matches)一个给定的 cookie-path 至少需要满足以下条件中的一个:
注意:domain-matching & path-matching 只是浏览器决定是否携带 cookie 诸多参考项中的其中两个,浏览器还会参考诸如是否过期等项。
cookie 不设置失效时间的话,默认是会话结束失效,这个会话结束是指浏览器的所有窗口都关闭,还是说这个网站的页面全部关闭就可以了?
Chrome 浏览器开了两个窗口 A B,A 打开了网站 1 的两个标签页(tab1 & tab2)和网站 2 的两个标签页(tab3 & tab4),B 打开了网站 1 的两个标签页(tab1 & tab2)和网站 2 的两个标签页(tab3 & tab4),如果想网站 1 的 cookie 失效的话,是不是把窗口 A B 关于网站 1 的 tab 页关掉就行 还是 需要把浏览器的所有窗口都关闭?
https://segmentfault.com。它的 PHPSESSION 是会话结束失效,所以用来测试。
通过 chrome://settings/cookies/detail?site=segmentfault.com 查看该网站下的所有 cookie。
浏览器的所有窗口都关闭,网站 1 的 cookie(会话 cookie)才失效。windows 在浏览器窗口都关闭的情况下,会退出程序,所以 cookie 会失效;mac 在浏览器窗口都关闭的情况下,不会退出程序,所以 cookie 不会失效,需要退出程序 cookie 才失效。
如果一个 cookie 同时设置了 Max-Age 和 Expires 属性,Max-Age 的优先级更高。如果两个都没有设置,UA 会保存该 cookie 直到当前 会话结束。
共计 2771 个字符,预计需要花费 7 分钟才能阅读完成。
HTTP 协议是一种无状态的协议,Web 服务器本身不能识别出哪些请求是同一个浏览器发出的,浏览器的每一次请求都是完全孤立的。
web 服务器怎么唯一地标识一个用户,并记录该用户的状态?
会话指一个客户端与 web 服务器之间连续发生的一系列请求和响应过程。(就像把电话拿起到最后挂断)。
会话状态指 web 服务器与浏览器在会话过程中产生的状态信息,借助会话状态,web 服务器把属于同一会话中的一系列请求和响应过程关联起来。
web 服务器要从大量的请求消息中区分出哪些请求属于同一会话,即能识别出来自同一个浏览器的访问请求,这需要浏览器对其发出的每个请求消息都进行标识:属于同一个会话中的请求消息都附带同样的标识号,属于不同会话的请求消息附带不同的标识号,这个标识号就称为会话 ID。
servlet 规范中,有两种机制完成会话跟踪:
cookiesession
是客户端保持 HTTP 状态信息的一种方案。
浏览器访问 web 服务器的某个资源时,由 web 服务器在 HTTP 响应消息头中附带传送给浏览器的一个小文本文件(Set-Cookie 响应头字段)。如:
Set-Cookie: bid=8UKoeCtJT1M; Expires=Sat, 25-Apr-20 04:02:11 GMT; Domain=.douban.com; Path=/
一旦 web 浏览器保存了某个 cookie,那么它在以后每次访问该 web 浏览器时都会在 HTTP 请求头中(Cookie 请求头字段)将这个 cookie 回传给 web 服务器。如:
Cookie: bid=8UKoeCtJT1M;
如果浏览器不支持 Cookie(如大部分手机中的浏览器)或者把 Cookie 禁用了,Cookie 功能就会失效。
不同的浏览器采用不同的方式保存 Cookie。
IE 浏览器会在 C:\Documents and Settings\ 你的用户名 \Cookies
文件夹下以文本文件形式保存,一个文本文件保存一个 Cookie。
httpServletResponse.addCookie(cookie);
该方法并不修改之前的 Set-Cookie 报头,而是创建新的报头。
一个 web 站点可以给一个 web 浏览器发送多个 cookie,一个浏览器也能存储多个 web 站点提供的 cookie(每个站点最多存放 20 个)。一个 cookie(大小限制为 4kb)只能标识一种信息,它至 少含有一个标识该信息的 k -v。
Cookie 的值。如果值为 Unicode 字符,需要为字符编码。如果值为二进制数据,则需要使用 BASE64 编码。
httpServletRequest.getCookies()
读取所有 cookie 返回数组,遍历通过 cookie.getName()筛选出自己要的(new Cookie()时的第一个参数)。
如果要修改某个 Cookie,只需要新建一个同名的 Cookie,添加到 response 中覆盖原来的 Cookie。
注意:修改、删除 Cookie 时,新建的 Cookie 除 value、maxAge 之外的所有属性,例如 name、path、domain 等,都要与原 Cookie 完全一样。否则,浏览器将视为两个不同的 Cookie 不予覆盖,导致修改、删除失败。
cookie 的时效性:
默认情况下新建的 cookie 是一个会话级别的 cookie(会话 cookie),存储在浏览器内存中,用户关闭浏览器后被删除。
若希望浏览器将该 cookie 存储在磁盘上(持久 cookie),需要使用 maxAge,并给出一个以秒为单位的时间。
如果为负数,该 Cookie 为临时 Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该 Cookie。这种 cookie 直到超过设定的过期时间才被删除。如果为 0,表示删除该 Cookie。默认为–1。
cookie 的作用范围:
默认是当前目录以及子目录,不能作用于上一级目录。
可以自己设置 cookie 的作用范围:setPath(request.getContextPath)
“/”表示站点的根目录,如果设置为“/”,则本域名下 contextPath 都可以访问该 Cookie。
Cookie 是不可跨域名的。域名 www.google.com 颁发的 Cookie 不会被提交到域名 www.baidu.com 去。这是由 Cookie 的隐私安全机制决定的。隐私安全机制能够禁止网站非法获取其他网站的 Cookie。
正常情况下,同一个一级域名下的两个二级域名如 www.baidu.com 和 images.baidu.com 也不能交互使用 Cookie,因为二者的域名并不严格相同。如果想所有 baidu.com 名下的二级域名都可以使用该 Cookie,需要设置 Cookie 的 domain 参数为.baidu.com。
可以修改本机 hosts 文件来配置多个临时域名来验证 domain 属性。
注意:domain 参数必须以点 (“.”) 开始。另外,name 相同但 domain 不同的两个 Cookie 是两个不同的 Cookie。如果想要两个域名完全不同的网站共有 Cookie,可以生成两个 Cookie,domain 属性分别为两个域名,输出到客户端。
HTTP 协议不仅是无状态的,而且是不安全的。使用 HTTP 协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用 HTTP 协议传输很机密的内容是一种隐患。如果不希望 Cookie 在 HTTP 等非安全协议中传输,可以设置 Cookie 的 secure 属性为 true。浏览器只会在 HTTPS 和 SSL 等安全协议中传输此类 Cookie。设置 secure 属性为 true 的代码是 cookie.setSecure(true);
secure 属性并不能对 Cookie 内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对 Cookie 内容加密(不可逆加密的)、解密,以防泄密。
expires: 失效时间,表示 cookie 何时应该被删除的时间戳(也就是,何时应该停止向服务器发送这个 cookie)。如果不设置这个时间戳,浏览器会在页面关闭时即将删除所有 cookie;不过也可以自己设置删除时间。这个值是 GMT 时间格式,如果客户端和服务器端时间不一致,使用 expires 就会存在偏差。
HttpOnly: 告知浏览器不允许通过脚本 document.cookie 去更改这个值,同样这个值在 document.cookie 中也不可见。但在 http 请求张仍然会携带这个 cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。这项设置通常在服务器端设置。
自动登入
购物车,最近浏览过的商品