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网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装

JavaScript单行代码,也就是代码片段

XSS:如何从 C# 中的字符串中删除 JS 片段?

代码片段:Shell脚本实现重复执行和多进程