14Cookie
Posted 三十六烦恼风x
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了14Cookie相关的知识,希望对你有一定的参考价值。
1.1. 会话技术
1.1.1. 会话概述
会话可简单理解为:用户开一个浏览器,访问多个资源,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
在浏览器和服务器建立链接之后,浏览器和服务器为了完成某一功能,浏览器发送一次或多次请求,服务器作出的一次或多次响应,在浏览器关闭之前,所有的请求和响应就构成了一次会话。
1.1.2. HTTP协议特点:
HTTP无状态协议:当前请求和上一次请求之间没有任何的联系。
1.1. 3. 使用会话技术的原因:
为了能够在多次请求响应之间共享数据,所有提出会话技术。
1.1.2. 会话中的问题
每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
如用户登录过后,应该保存一个用户状态,在会话结束前表明用户一直是登录状态。并且不同的用户之间的登录状态应该互不影响。
我们之前已经学过request域和SerlvetContext域,我们分别分析一下。
Request域太小了,在多次请求中,每次请求响应都是新的Request对象,之前存入的request域中的域属性,在请求结束后随着request域的销毁而消失了。
ServletContext域太大了,所有用户都在操作这个域,必然会发生混乱。
此时我们需要会话相关的技术,保存会话产生的数据。
2.Cookie会话技术
a. cookie的实现原理
服务器会在第一次响应的时候,通过set-cookie响应头,将需要使用的数据发送到浏览器,浏览器会自动将其作为cookie保存。在下一次请求时,会自动携带一个cookie请求头,其中包含的内容就是浏览器中的cookie信息。
b. cookie特点:
cookie技术是一门浏览器端的技术,数据保存在浏览器端。保存安全性要求较低的数据。而存储时间较长的数据。
c. 案例:返回上次访问页面的时间:
i. 在第一响应中,set-cookie保存的数据会到达浏览器。并且保留在浏览器中。
ii. 在下一次的请求中,使用cookie请求头,获取cookie,得到结果。
代码实现:
package cn.tedu.cookie; import java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //cookie原理实现 public class CookieDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //乱码解决 response.setContentType("text/html;charset=utf-8");//解决的是响应时服务器发送和浏览器接收数据乱码 //返回页面上一次的访问时间 Date date = new Date(); String time = date.toLocaleString();//获取当前时间 //1.设置set-cookie响应头 response.setHeader("set-cookie", "time="+time); //2.获取请求头cookie String cookie = request.getHeader("cookie"); //3.打印结果 if(cookie == null){//初次请求没有cookie请求头,所以cookie请求头为null response.getWriter().write("您是初次访问本页面"); }else{ response.getWriter().write("上次访问页面的时间为:"+cookie); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
1.1.1. Cookie常用方法
1. Cookie类
Sun公司提供了一个Cookie类,可以通过创建对象的方式,来创建cookie。
//1.1--javax.servlet.http.Cookie类用于创建一个Cookie对象
Cookie cookie = new Cookie(String name,String value);
1.2设置和获取cookie的值
setValue与getValue方法
getName方法
--cookie需要在创建时就指定好名字,这个名字一旦指定就不能修改了,如果需要修改只能重新创建一个cookie
setMaxAge与getMaxAge方法
--一个cookie被发送到浏览器时,如果没有设置过MaxAge,这个cookie将会被保存在浏览器的内存中,会一直存在到浏览器关闭内存销毁为止,这样的cookie叫做会话级别的Cookie
--我们也可以使用setMaxAge方法设置cookie的存活时间,这样一来,浏览器收到这个Cookie信息时会将cookie信息以文件的形式保存在浏览器的临时文件夹中,保存到指定的时间到来位置,在这个期间即使多次开关浏览器,cookie信息一直都在.如果设置生命时长,则达到对应时间之后,会有浏览器自动销毁。
cookie.setMaxAge(单位是秒);
setPath与getPath方法
--设置浏览器在访问哪个地址及其子地址时,带着cookie信息过来.如果没设置过,那么默认的path是当前发送cookie的Servlet所在的路径
cookie.setPath(request.getContextPath()+"/"); //这个是设置成web应用下的路径或子路径都可以带着cookie信息过来。cookie.setpath("/")代表的意思是缺省应用的路径, 而getContextPath()在获取缺省web应用的路径时,返回的是空.所以为了保证缺省web应用也可以被选择到,所以要+"/"
setDomain与getDomain方法
--设置浏览器在访问哪个域名时,带着当前的cookie,默认值当前发送cookie的域名,注意,现代的浏览器只要发现cookie设置过domain属性,则认为这个cookie是第三方cookie,会拒绝接受.cookie的domain默认是一样的。
1.1.2. 发送cookie
response.addCookie(cookie);
--response接口也中定义了一个setHeader方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。
1.1.3. 获取cookie
request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。
Cookie [] cs = request.getCookies();
1.1.4. 删除cookie
浏览器会通过name+path+domaint来区分cookie,如果浏览器发现两个cookie名字 path domain 都相同,则会认为是相同的cookie,就会发送cookie的覆盖。
所以如果想要删除一个cookie,可以发送一个和要删除的cookie名字 path (domain) 都相同的cookie,然后将这个cookie的maxAge设置为0,这样一来,这个cookie会把要删除的cookie覆盖掉,覆盖后立即超时,直接被浏览器删除,看起来就像是删除了要删除的cookie
而因为domain所有的cookie都默认相等,所以我们设置name和path就好
domain详解:
domain的含义为域
假设有两个域名
a.b.e.f.com.cn 以下用域名1指代此域名
c.d.e.f.com.cn 以下用域名2指代此域名
在域名中,所有域名进行分级,也就是说域名1与域名2都是f.com.cn的子域名,f.com.cn又是com.cn的子域名
在域名1所使用的服务中,可以设置域名
a.b.e.f.com.cn
b.e.f.com.cn
e.f.com.cn
f.com.cn
在服务端设置domain的时候,设置domain为b.e.f.com.cn或.b.e.f.com.cn没有区别,注意前面的点,即只要是为cookie显式的声明domain,前面带不带点没有区别。这个点的奥妙后面还会提到。
设置其他域名虽然可以在响应头中有set-cookie的头,但是出于安全考虑,该头会被浏览器忽略,并不会产生真实的cookie,有一点注意,虽然在域名上来说,f.com.cn是com.cn的子域,但是浏览器是不会接收domain为com.cn的cookie的,那样互联网就乱套了。
对于域名1下的cookie,域名2可以拿到e.f.com.cn,f.com.cn这两个domain下的cookie,互联网上说的单点登录,就是以这个原理实现的。
如果存在相同名的cookie不同domain呢?
比如域名1设置设置domain为e.f.com.cn的cookie,mykey=myvalue1。
而在域名二中设置domain为c.d.e.f.com.cn的cookie,mykey=myvalue2。
此时在域名2服务端能拿到两个cookie都为mykey=myvalue,并不存在覆盖一说。
注意在域名2中如果设置domain为e.f.com.cn的cookie,mykey=myvalue3.此时会覆盖域为e.f.com.cn的mykey的值,即浏览器中,同一个域,只存在一个名为mykey的cookie。
如果不显式设置cookie,默认当前域名这种说法对不对呢?
先说第一个问题,如果不显示设置cookie,那么浏览器会生成一个只针对当前域名的cookie,什么叫只针对当前域名呢?
如果有一个域名就是e.f.com.cn,在该域名下设置的cookie如果没有显示domain,在回写浏览器的时候浏览器会特殊处理,如果是火狐,你会发现该cookie的信息,有一个主机项,而域项消失了,在chrome中,虽然有域这个项,但是域的前面少了一个点,就是上面所说的,如果显示声明,不管域中带不带点,到chrome中,都是带点存储的,只有非显式声明域的cookie,浏览器存储才是不带点的,问题就在这,在e.f.com.cn服务主机中生成的cookie,只有e.f.com.cn的服务器能拿到,此时子域名是拿不到这个cookie得。
1.1.5. Cookie细节
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
注意,删除cookie时,path必须一致,否则不会删除(浏览器通过cookie的name+path来标识一个cookie)
1.1.1. URL编码原理
略
1.1.2. URL编解码
Java中提供了进行URL编码和解码的类
URLEncoder:static String encode(String s,String enc);
//将指定的字符串按照指定的编码转换为URL编码的形式
URLDecoder:static String decode(String s,String enc);
//将URL编码后的字符串按照指定编码解码为源字符串
例子:
//cookie存放的格式是utf-8
取出时解码方式也是utf-8
以上是关于14Cookie的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段14——Vue的axios网络请求封装
VSCode自定义代码片段14——Vue的axios网络请求封装