首页IT科技会话是啥意思(客户端会话跟踪技术 Cookie 浅谈)

会话是啥意思(客户端会话跟踪技术 Cookie 浅谈)

时间2025-05-02 21:23:48分类IT科技浏览3319
导读:前言 用户打开浏览器,第一次访问 Web 服务器资源时,会话建立,直到有一方断开了连接则会话结束,例如浏览器或者服务器断开。在一次会话中可以包含多次的请求和响应。...

前言

用户打开浏览器           ,第一次访问 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); } }

访问服务器资源                ,如图:

此时            ,在控制台打印了没有乱码的中文数据               。如图:

声明:本站所有文章   ,如无特殊说明或标注                ,均为本站原创发布                。任何个人或组织               ,在未征得本站同意时,禁止复制           、盗用                、采集      、发布本站内容到任何网站         、书籍等各类媒体平台  。如若本站内容侵犯了原著者的合法权益             ,可联系我们进行处理            。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
朴素贝叶斯 例题(机器学习:基于朴素贝叶斯对花瓣花萼的宽度和长度分类预测) 网络优化排名增长技巧大全(成为搜索引擎界的翘楚,让你的网站名闻遐迩)