客户端会话跟踪技术 Cookie 浅谈
Posted 橙 子_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了客户端会话跟踪技术 Cookie 浅谈相关的知识,希望对你有一定的参考价值。
文章目录
前言
用户打开浏览器,第一次访问 Web 服务器资源时,会话建立,直到有一方断开了连接则会话结束,例如浏览器或者服务器断开。在一次会话中可以包含多次的请求和响应。
上述的整个过程称为会话。
例如,当我们在浏览器访问一个网站时,浏览器和这个网站服务器就建立了一次会话,后面在这个网站中的所有操作都属于这一次会话,当我们关闭浏览器程序或者服务器关闭则会话结束。
现实中,服务器会被多个用户同时访问,为了识别多次请求是否来自同一个浏览器,在一次会话的多次请求间共享数据,出现了会话跟踪技术。会话跟踪技术是一种维护浏览器状态的方法,服务器识别浏览器的过程就被称为会话跟踪。
例如,实现购物车的功能中,第一次请求,用户将商品加入购物车,下一次请求,用户去购物车结算,第二次请求需要展示前一次添加到购物车中的商品,此时就要用到数据共享。再比如说页面展示用户的登录信息,网站登录页面记住密码等功能,都会用到数据共享。
为什么之前浏览器和服务器不支持数据共享?
之前说过,浏览器和服务器之间使用 HTTP 协议请求来传输数据,而 HTTP 协议是无状态的,也就是说浏览器发起的两次请求是毫不相干的,,每次浏览器向服务器发起请求时,服务器都会将该请求视为新的请求。
HTTP 协议之所以无状态,是因为该协议想让每次请求之间相互独立,互不影响,提高了性能,但是也伴随着多次请求之间数据无法共享的问题,而会话跟踪技术正是解决了这个难题。
会话跟踪技术
我们有两种方式来实现会话跟踪技术,分别是客户端会话跟踪技术 Cookie 和服务器会话跟踪技术 Session。其中 Cookie 是存储在客户端浏览器的,而 Session 是存储在服务器端的。两者各有利弊,接下来我们可以从两者的原理,使用等一同探讨。
什么是 Cookie,Cookie 是如何实现的?如何使用?接下来带着这些问题深入研究。
Cookie的概念
Cookie 是指客户端会话跟踪技术,其特点是将数据保存到客户端,以后每次请求都会携带 Cookie 数据进行访问。
Cookie的工作流程
浏览器发送 HTTP 请求给 Web 服务器资源时,服务器资源接收请求并进行业务处理,在这个过程中会创建一个 Cookie 对象,并将请求参数中的数据存入 Cookie。服务器响应数据时会把 Cookie 对象响应给浏览器,浏览器接收到响应后,会把 Cookie 中的数据存放到浏览器内存中,在同一次会话中浏览器再一次发送请求给 Web 服务器资源时,会携带 Cookie 对象中的所有数据。此时就实现了同一会话的不同请求之间的数据共享。
例如:
如上图,浏览器第一次访问 Web 服务器时,会话建立,那么如何实现一次会话的多次请求之间的数据共享呢?
浏览器发送 HTTP 请求 1 给服务器,服务器 Servlet 1 接收请求并进行业务处理,在处理过程中创建 Cookie 对象并将数据 name=zhangsan
存入 Cookie 。响应数据时,Cookie 对象被响应到浏览器,浏览器接收到响应数据会把 Cookie 对象中的数据存放到浏览器内存中,此时会话建立。
在同一次会话中,浏览器发送 HTTP 请求 2 给服务端 Servlet 2,此时会携带 Cookie 对象中所有的数据。 Servlet 2 接收到请求和数据后,就可以获取到 Cookie 对象中的数据,实现了一次会话中多次请求的数据共享。
Cookie的基本使用
对于 Cookie 的使用,我们主要关注后台代码对 Cookie 的操作,Cookie 的操作主要分为发送 Cookie 和接收 Cookie。
发送 Cookie:
创建 Cookie 对象:
Cookie cookie = new Cookie("key","value");
发送 Cookie 到浏览器:
response.addCookie(cookie);
下面练习将 Cookie 发送到客户端浏览器。
第一步:
创建 Maven Web 项目,命名为 cookie-demo,在 pom.xml 中添加相关依赖。
<dependencies>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!--jstl-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
第二步:编写 Servlet,编码:
@WebServlet("/servletA")
public class ServletA extends HttpServlet
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
//创建Cookie对象
Cookie cookie = new Cookie("name", "zhangsan");
//通过response发送Cookie对象
response.addCookie(cookie);
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
this.doGet(request, response);
第三步:启动服务器,在浏览器中访问对象的服务器资源。
不难发现,此时响应数据中已经携带了 Cookie 的数据,如图:
浏览器中存储的 Cookie 数据怎么查看呢?一般情况下我们可以通过浏览器的设置查看,在不同的浏览器设置中一般都有 Cookie 选项,我们发现其中就存放了很多的 Cookie 数据。如图:
同样的我们也可以通过 F12 开发者工具查看,如图:
获取 Cookie:
获取客户端携带的所有 Cookie:
Cookie[] cookie = request.getCookies();
使用 Cookie 对象方法获取数据:
cookie.getName();
cookie.getValue();
我们只需要遍历数组对象,并且使用 Cookie 对象方法,便可以获取每一个 Cookie 对象对应的值。
下面练习获取浏览器请求中的 Cookie 数据。
第一步:编写一个 Servlet,命名为 ServletB,编码:
@WebServlet("/servletB")
public class ServletB extends HttpServlet
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
//获取Cookie数组
Cookie[] cookies = request.getCookies();
//遍历数组对象
for(Cookie cookie:cookies)
//获取数据
String name = cookie.getName();
if("name".equals(name))
String value = cookie.getValue();
System.out.println(name+":"+value);
break;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
this.doGet(request, response);
第二步:在浏览器访问对应的资源,此时控制台输出了从浏览器获取的 Cookie 对象的值。如图:
在一次会话中,我们使用浏览器访问了两个不同的资源 ServletA 和 ServletB,并且实现了数据的共享。当我们关闭浏览器重新启动后访问 ServletB,此时会发现我们已经无法访问到 name:zhangsan 这条数据了。
Cookie原理分析
Cookie 的实现是基于 HTTP 协议的,其中涉及到了下面两个信息:
- 响应头:set-cookie
- 请求头:cookie
例如在上面的案例中:
我们在前面的案例中使用 request 在 ServletB 中获取到了 Servlet 响应给浏览器的数据,在同一会话的两次请求之间实现了数据共享。
在 ServletA 响应数据时,Tomcat 服务器是基于 HTTP 协议来实现的,当 TomCat 发现要响应一个 Cookie 对象时,就会在响应头重添加数据:
set-Cookie:name=zhangsan
浏览器获取当响应结果后,从响应头中获取到对应的值 name=zhangsan ,并将数据存储在浏览器内存中。
在同一次会话中,浏览器发送 HTTP 请求给 ServletB,浏览器会自动在请求头中添加:
Cookie:name=zhangsan
服务器接收到浏览器的请求,Request 对象会将请求头中的 cookie 对应的值封装为 Cookie 对象,存放在数组中。此时我们就可以根据需求获取数据。
例如:
访问 ServletA 时,查看响应头数据如下:
访问 ServletB 时,查看请求头数据:
Cookie的存活时间
思考:
前面我们通过 ServletA 响应了存放 name=zhangsan 的 Cookie 对象给浏览器,浏览器接收响应数据并将 Cookie 数据存放到浏览器内存中,通过浏览器再次发送 HTTP 请求给 ServletB,并且使用 Response 对象获取了 Cookie 数据,那么在向 ServletB 发送请求之前,如果我们将浏览器彻底关闭并重新打开,还能通过 ServletB 获取到 Cookie 数据吗?
通过测试不难发现,如果将浏览器彻底关闭再次打来访问 ServletB 时,我们无法获取 Cookie 对象数据。
Cookie 的存活时间是指从创建到销毁的整个时间,那么 Cookie 对象能存活多久呢?
因为 Cookie 存放在浏览器内存中,所以在默认情况下,如果浏览器关闭,内存释放,此时 Cookie 就会被销毁。这也是为什么案例中我们再次打开浏览器无法获取 Cookie 的原因。
但是,有时我们需要 Cookie 的数据持久化存储,例如在实现登录时记住我的功能时,我们希望再次打开浏览器访问登录页面时,数据能被重新获取。Cookie 提供了对应的 API 来解决这个问题,我们可以通过 setMaxAge() 方法来设置 Cookie 的存活时间。
setMaxAge(int seconds)
参数为存活的秒数,通过设置其参数来控制 Cookie 的存活时间:
- 正数:将 Cookie 写入浏览器所在的电脑硬盘吗,持久化存储,到指定时间后自动删除
- 负数:默认值,存放在浏览器内存中,浏览器关闭,内存释放,Cookie 销毁
- 零:删除对应的 Cookie
示例:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
//创建Cookie对象
Cookie cookie = new Cookie("name", "zhangsan");
//设置Cookie存活时间
cookie.setMaxAge(60*60*24*7);
//通过response发送Cookie对象
response.addCookie(cookie);
设置完 Cookie 存活时间后,我们重启服务器,在浏览器访问 ServletA,重启浏览器,再次访问 ServletB,此时不难发现,Cookie 数据能够被获取到,说明 Cookie 并没有因为浏览器内存释放而销毁。
在浏览器设置中我们也可以看到,有些 Cookie 数据甚至设置存放一年之久。如图:
Cookie存储中文
其实在之前的案例中,如果我们设置的参数值为中文的话,在浏览器访问时会被提示错误信息的,因为 Cookie 是不能直接存储中文的。那么如果我们有存储中文的需求时该怎么解决这个问题呢?
这里就又要用到 URL 编码,具体怎么实现呢?
例如上面的例子中,在 ServletA 中响应 Cookie 数据时,对中文数据进行 URL 编码,并且将编码后的数据存放到 Cookie 中,在 Servlet 中获取 Cookie 的值时,只需要附加的进行 URL 解码,变不会出现中文乱码的问题。
示例:
第一步:在 ServletA 中进行 URL 编码:
@WebServlet("/servletA")
public class ServletA extends HttpServlet
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
//数据
String s = "张三";
//URL编码
String encode = URLEncoder.encode(s, "utf-8");
System.out.println(encode);
//将编码后的数据存放到Cookie中
Cookie cookie = new Cookie("name", encode);
//设置Cookie存活时间
cookie.setMaxAge(60*60*24*7);
//通过response发送Cookie对象
response.addCookie(cookie);
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
this.doGet(request, response);
访问服务器资源,如图:
第二步:在 ServletB 中进行 URL 解码:
@WebServlet("/servletB")
public class ServletB extends HttpServlet
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
//获取Cookie数组
Cookie[] cookies = request.getCookies();
//遍历数组对象
for(Cookie cookie:cookies)
//获取数据
String name = cookie.getName();
if("name".equals(name))
//获取数据
String value = cookie.getValue();
//URL解码
value = URLDecoder.decode(value, "utf-8");
System.out.println(name+":"+value);
break;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
this.doGet(request, response);
访问服务器资源,如图:
此时,在控制台打印了没有乱码的中文数据。如图:
会话跟踪之Cookie技术
1. Cookie会话跟踪技术介绍
会话跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,可以在客户端保存临时数据.
Cookie 技术诞生以来,它就成了广大网络用户和 Web 开发人员争论的一个焦点。有一些网络用户,甚至包括一些资深的 Web 专家也对它的产生和推广感到不满,这并不是因为 Cookie 技术的功能太弱或其他技术性能上的原因,而是因为 Cookie 的使用对网络用户的隐私构成了危害。因为 Cookie 是由 Web 服务器保存在用户浏览器上的小文本文件,它包含有关用户的信息.
Cookie 技术产生源于 HTTP 协议在互联网上的急速发展。随着互联网的深层次发展,带宽等限制不存在了,人们需要更复杂的互联网交互活动,就必须同服务器保持活动状态。于是,在浏览器发展初期,为了适应用户的需求,技术上推出了各种保持 Web 浏览状态的手段,其中就包括了 Cookie 技术。1993 年,网景公司雇员 Lou Montulli 为了让用户在访问某网站时,进一步提高访问速度,同时也为了进一步实现个人化网络,发明了今天广泛使用的 Cookie.
Cookie 是在 HTTP 协议下,服务器或脚本可以维护客户工作站上信息的一种方式。Cookie 是由 Web 服务器保存在用户浏览器(客户端)上的小文本文件,它可以包含有关用户的信息。无论何时用户链接到服务器,Web 站点都可以访问 Cookie 信息
目前有些 Cookie 是临时的,有些则是持续的。临时的 Cookie 只在浏览器上保存一段规定的时间,一旦超过规定的时间,该 Cookie 就会被系统清除
持续的 Cookie 则保存在用户的 Cookie 文件中,下一次用户返回时,仍然可以对它进行调用。在 Cookie 文件中保存 Cookie,有些用户担心 Cookie 中的用户信息被一些别有用心的人窃取,而造成一定的损害。其实,网站以外的用户无法跨过网站来获得 Cookie 信息。如果因为这种担心而屏蔽 Cookie,肯定会因此拒绝访问许多站点页面。因为,当今有许多 Web 站点开发人员使用 Cookie 技术,例如 Session 对象的使用就离不开 Cookie 的支持.
会话跟踪技术是用于维持客户端和服务器端通信信息的技术, 而Cookie是其中的一种会话跟踪技术;
Cookie是在http协议下,服务器或脚本可以维护客户端信息的一种方式,
Cookie保存在客户端,通常保存在浏览器的Cookie临时文件夹中,可以手动删除,
当用户访问服务器时,服务器可以设置和访问cookie的信息
Cookie利用了网页代码中的HTTP头信息进行传递的,浏览器的每一次网页请求,都可以伴随Cookie传递
2. Cookie的机制
在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。
由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
Cookie在你浏览网页的时候,网站服务器放在客户端(Client End,就是你的电脑)里面的一个小小的TXT文件。这个文件里面存储了一些与你访问的这个网站有关的一些东西,当你下一次访问这个网站的时候,Cookie就会记住你上次访问时候的一些状态或者设置,让服务器针对性的发送页面的相关内容。Cookie里面包含的信息并没有一个标准的格式,各个网站服务器的规范都可能不同,但一般会包括:所访问网站的域名(domain name),访问开始的时间,访问者的IP地址等客户端信息,访问者关于这个网站的一些设置等等。比如,你设置的诸如Google一个页面要显示几条搜索结果之类的信息,即使你不登录你的Google账号,你下次访问时也能够保存下来,这就是上次你访问时把相关信息放入了Cookie的效果。如果是在线购物网站,还记录了一些你的购物车,储物架以及你的账户名等信息。另外有些网站则会通过Cookie把你的登录账号和密码记下来,这样你下次打开浏览器就会自动登录。
当然,如果你在系统文件夹中打开Cookie的TXT文件,你并不会看到这些信息而只能看到一串乱七八糟的字符,因为为了安全起见,Cookie的内容一般都是加密的,只有对应的服务器才能读懂。另外,由于Cookie只是TXT文件,而不是程序,更不是病毒,不能自己运行,不会对操作系统和其他任何计算机程序产生影响,也不会通过互联网传播,因此它对互联网安全实际上不构成威胁。
对于网站分析而言,Cookie的作用在于帮助嵌入代码类的网站分析工具记录网站的访问(Visit)和访问者(Unique Visitor)的信息,没有Cookie就无法实现相关监测。而通过服务器端Log来进行网站分析的软件则不需要Cookie也能实现相关分析,因此 Cookie只对嵌入代码类工具有效。那些你耳熟能详的工具——Google Analytics、Omniture、HBX、WebTrends(嵌入代码版)等等,都需要在网站访问者的电脑上放置Cookie才能实现监测。
3.Cookie如何使用
在JavaScript语言中,我们使用document.cookie: 获取/设置cookie
格式为: name=value;[expires=过期时间];[path=访问路径];[domain=域名];[secure]
如: document.cookie = "username=zhangsan";
4.Cookie的应用场景
4.1 自动登录
4.2电商购物车功能
4.3 记录用户登录网址的次数
4.4 商品浏览记录
5.电商购物车案例
在浏览器本地实现购物车功能
在商品详情界面, 我们可以点击加入购物车按钮, 将商品添加到购物车中, 该加入购物车的商品数据实际保存在Cookie中, 商品详情页面如下图:
添加多个商品到购物车后, 我们可以前往我的购物车中查看购物车中的商品,这些商品数据我们都是从cookie中获取的, 如下图:
购物车商品显示后我们可以继续对购物车中的每个商品进行操作, 如数量的增减, 商品删除, 价格统计, 批量删除, 全选等操作, 如下图可以对商品进行删除, 在删除的同时我们也会对Cookie中的数据进行同步更改.
以上是关于客户端会话跟踪技术 Cookie 浅谈的主要内容,如果未能解决你的问题,请参考以下文章