域(Domain)
子域,是相对父域来说的,指域名中的每一个段。各子域之间用
小数点分
隔开。放在域名最后的子域称为最高级子域,或称为一级域,在它前面的子域称为二级域。一个“.”代表一个层次,如域child.Microsoft.com 就比 Microsoft.com这个域级别低,因为它有两个层次关系,而Microsoft.com
只有一个层次
。而域Grandchild.Child.Microsoft.com又比 Child.Microsoft.com级别低,道理一样。他们都属于同一个域树。Child.Microsoft.com就属于Microsoft.com的子域。
一、 Cookie
Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上
。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的HTTP协议记录稳定的状态信息成为了可能。 Cookie主要用于以下三个方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
二、Cookie的一些属性
属性名 | 属性说明 |
---|---|
maxAge | Cookie有效期,单位秒。如果为整数,则该Cookie在maxAge秒后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。如果为0,表示删除该Cookie。默认为-1 |
Expires | Cookie的失效时间,如果Cookie没有设置过期时间,那么 cookie 的生命周期只是在当前的会话中,关闭浏览器意味着这次会话的结束,此时 cookie 随之失效, 现在已经被maxAge属性所取代 |
secure | 它是一个布尔值,指定在网络上如何传输Cookie,默认为false,通过一个普通的http连接传输,标记为true的Cookie只应通过被 HTTPS 协议加密过的请求发送给服务端 |
path | Cookie的使用路径,path标识指定了主机下的哪些路径可以接受 Cookie(该 URL 路径必须存在于请求 URL 中), 例如:如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie,如果设置为“/”,则本域名下contextPath都可以访问该Cookie。注意最后一个字符必须为“/” |
domain |
|
-
domain:创建此cookie的服务器主机名(or域名),服务端设置。但是
不能
将其设置为服务器所属域之外的域(若这都允许的话,你把Cookie的域都设置为baidu.com,那百度每次请求岂不要“累死”)
默认值是创建cookie的服务器的主机名
-
注:端口和域无关
,也就是说Cookie的域是不包括端口的
-
-
path:域下的
哪些目录
可以访问此cookie,
默认为/
,表示所有目录均可访问此cookie 创建该cookie的服务器的根目录。
同域Cookie
:每次访问的是同一个域下的不同页面、API
不同域Cookie
:同一个浏览器窗口内可能同时访问A网站和B网站,它们均有各自的Cookie,但访问A时只会带上A的Cookie
跨域Cookie共享
:访问A站点时已经登录从而保存姓名、头像等基本信息,这时访问该公司的B站点时就自然而然的能显示出这些基本信息,也就是实现信息共享
关于端口问题:
cookie在不同的端口下可以共享,根据同源策略cookie是区分端口的,但是对浏览器来说,cookie是区分域,不区分端口的,在一个ip地址下多个端口的cookie是共享的
由于历史原因,cookie包含了许多安全和隐私违规行为。例如,服务器可以指示给定的cookie用于“安全”连接,但在活动网络攻击者的存在下,安全属性不提供完整性。
类似地,给定主机的cookie在主机上的所有端口之间共享,尽管Web浏览器通常使用的“相同来源策略”将通过不同端口检索的内容隔离开来。
Cookie不提供端口隔离。
..如果Cookie是由运行在一个端口上的服务读取的,那么运行在同一服务器的另一个端口上的服务也可以读取Cookie。如果Cookie可由一个端口上的服务写入,则该cookie也可由运行在同一服务器的另一个端口上的服务写入。因此,服务器不应既在同一主机的不同端口上运行相互不信任的服务,又使用cookie存储安全敏感信息。
三、Cookie的交互机制
下面这张图完整的说明了Cookie的交互机制,共四个步骤:
1、浏览器(客户端)发送一个请求到服务器
2、服务器响应。并在HttpResponse里增加一个响应头:Set-Cookie
3、浏览器保存此cookie在本地,然后以后每次请求都带着它,且请求头为:Cookie
4、服务器收到请求便可读取到此Cookie,做相应逻辑后给出响应
由此可见,Cookie用于保持请求状态,而这个状态依赖于浏览器端(客户端)的本地存储。
四、Cookie的生命周期
缺省情况下,Cookie的生命周期是Session级别(会话级别)。若想用Cookie进行状态保存、资源共享,服务端一般都会给其设置一个过期时间maxAge,短则1小时、1天,长则1星期、1个月甚至永久,这就是Cookie的生命(周期)。Cookie的存储形式,根据其生命周期的不同而不同。这由maxAge属性决定,共有这三种情况:
1、maxAge > 0
:cookie不仅内存里有,还会持久化到硬盘,也叫持久Cookie。这样的话即使你关机重启(甚至过几天再访问),这个cookie依旧存在,请求时依旧会携带
2、maxAge < 0
:一般值为-1,也就临时Cookie。该Cookie只在内存中有(如session级别),一旦管理浏览器此Cookie将不复存在。值得注意的是:
若使用无痕模式访问也是不会携带此Cookie的哟
3、maxAge = 0
:内存中没有,硬盘中也没有了,也就立即删除Cookie。此种case存在的唯一目的:服务浏览器可能的已存在的cookie,让其立马失效(消失)
Tips:请注意maxAge<0(负数)和maxAge=0的区别。前者会存在于内存,只有关闭浏览器or重启才失效;后者是立即删除
五、跨域Cookie的存储问题
默认情况下,
浏览器是不会去为你保存下跨域请求响应的Cookie的。
具体现象是:跨域请求的Response响应了即使有Set-Cookie响应头(且有值),浏览器收到后也是不会保存此cookie的。
要实现Cookie的跨域共享,有3个关键点:
1、服务端负责在响应中将Set-Cookie发出来(由
Access-Control-Allow-Credentials
响应头决定)
2、浏览器端只要响应里有Set-Cookie头,就将此Cookie存储(由异步对象的
withCredentials
属性决定)
3、浏览器端发现只要有Cookie,即使是跨域请求也将其带着(由异步对象的
withCredentials
属性决定)
六、跨域Cookie共享的三要素
首先确保服务端能正确的在响应中有Set-Cookie响应头,这由Access-Control-Allow-Credentials: true来保证。因此服务端只需要做多加这一步即可:
resp.setHeader(“Access-Control-Allow-Credentials”, “true”);
Access-Control-Allow-Credentials该头是可选的,是个bool值,它若为true就有两个作用:
1、在跨域请求的响应中允许Set-Cookie响应头
2、浏览器收到响应后,浏览器根据此头判断是否让自己的withCredentials属性生效
第二个要素
:XMLHttpRequest对象的withCredentials属性。当异步对象设置了withCredentials=true时,浏览器会保留下响应的Cookie等信息,并且下次发送请求时将其携带。
因此要指示浏览器存储Cookie并且每次跨域请求都携带,仅需加上此参数即可
:
以上两个要素完成后,影响“结果”的还有
最后一个要素
。
服务端的Access-Control-Allow-Origin这个响应头的值不能是通配符
*
,而只能是具体的值。否则出现报错:
换句话讲:浏览器端跨域请求对象一旦开启withCredentials=true属性,服务端跨域Origin将不能再用*通配符,否则CORS error!
三要素都满足(Access-Control-Allow-Credentials:true; Access-Control-Allow-Origin:http://localhost:63342; withCredentials=true)
七、业务场景
一般这样的操作,适用于单点登录,所谓单点登录是指用户在一个站点如www.studyez.com登录后切换到另一个站点communty.studyez.com时也自动 被community的Server判断为已经登录,反过来,只要用户在community.studyez.com登出后,切换到www.studyez.com时后www的Server也会判断到这一用户已经登出
参考: