文章目录
一、Cookie介绍
Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。Cookie最早由Netscape公司前雇员Lou Montulli在1993年3月发明。其主要目的是在客户端(如浏览器)存储会话信息,以帮助网站跟踪用户活动、记住用户偏好或身份验证信息等。
会话是由一组请求与响应组成,是围绕着一件相关事件所进行的请求响应。所以这些请求与响应之间一定是需要有数据传递的,即是需要进行会话状态跟踪。然而HTTP协议是一种无状态以协议,在不同的请求间是无法进行数据传递的,此时就需要一种可以进行请求间数据传递的会话跟踪技术,而Cookie就是这样的一种技术。
Cookie是由服务器生成,保存在客户端的一种信息载体。这个载体中存放着用户访问改站点的会话状态信息。只要Cookie没有被清空,或者Cookie没有失效,那么,保存在其中的会话状态就有效。
用户在提交第一次请求后,由服务器生成Cookie并将其封装到响应头中,以响应的形式发送给客户端。客户端接收到这个响应后,将Cookie保存到客户端。当客户端再次发送同类请求后,在请求中会携带保存在客户端的Cookie数据,发送到服务端,由服务器对会话进行跟踪。
Cookie技术并不是JavaWeb开发专属技术,而是数据Web开发的技术,是所有Web开发语言均支持的技术。
Cookie是由若干键值对构成,键称为name,值称为Value,键值均为字符串。
二、不同浏览器下的Cookie
不同的浏览器Cookie保存位置及其查看方式是不同的,删除了某一浏览器下的Cookie,不会影响到其他浏览器中的Cookie。
三、服务端生成与解析Cookie
1、服务端生成Cookie
2、服务端解析Cookie
四、Cookie中的属性设置及作用
在Web开发中,Cookie 是一种常用于在客户端存储少量数据并在多个页面或会话中跟踪用户状态的机制。Cookie 本质上是一个小的文本文件,它存储在用户的计算机上,并且可以在浏览器与服务器之间传递。
Cookie 可以包含多个属性,每个属性都有其特定的作用。以下是一些常见的 Cookie 属性及其作用:
- Name:
- 必需的属性,指定 Cookie 的名称。
- 通常在服务器端设置,并在客户端存储和发送回服务器时使用。
- Value:
- 必需的属性,指定与 Cookie 名称相关联的值。
- 可以是任何字符串,通常用于存储用户信息、会话标识符等。
- Domain:
- 指定可以接收 Cookie 的域名。
- 如果未设置,则默认为创建 Cookie 的页面所在的域名。
- 可以使用子域名来允许多个子域共享相同的 Cookie。
domain: 表示 "域"。若不指定则默认为创建 Cookie的服务器的域名.
分为子域和父域,子域可以访问"本级域名"及"父级域名"下的cookie。
请求 c.com 服务器响应回一个cookie的domain属性为 c.com,
那么接下来浏览器请求
a.c.com 服务器
b.c.com 服务器
a.b.c.com 服务器
,浏览器都会携带上这个cookie。
同理 浏览器访问 a.b.c.com,服务器响应一个cookie的domain属性为c.com
如果浏览器接着再访问 b.c.com 或者 c.com 同样这个cookie会被携带上
- Path:
- 指定服务器上哪些路径可以接收 Cookie。
- 如果未设置,则默认为创建 Cookie 的页面所在的路径。
- 例如,如果设置为 /path/,则只有 /path/ 及其子路径下的页面可以接收该 Cookie。
- Expires/Max-Age:
- Expires 属性定义 Cookie 的过期日期和时间。
- Max-Age 属性则指定从创建 Cookie 开始到过期的时间(以秒为单位)。
- 如果设置了这两个属性中的任何一个,Cookie 将成为持久性 Cookie,并在浏览器关闭后仍然存在。否则,它将成为会话 Cookie,并在浏览器关闭时过期。
- Secure:
- 如果设置为 true,则 Cookie 只能通过 HTTPS 连接传输,不能通过 HTTP 连接传输。
- 这增加了 Cookie 的安全性,因为它可以防止 Cookie 在不安全的网络上被截获。
- HttpOnly:
- 如果设置为 true,则 Cookie 只能通过 HTTP(或 HTTPS)访问,而不能通过客户端脚本(如 JavaScript)访问。
- 这可以防止跨站脚本攻击(XSS)中恶意脚本访问 Cookie。
- SameSite:
- 这是一个相对较新的属性,用于限制第三方网站对 Cookie 的访问。
- 它有三个可能的值:Strict、Lax 和 None。
- Strict:仅当 Cookie 从与创建它的站点相同的站点发送时才发送 Cookie。
- Lax:在大多数情况下与 Strict 相同,但在用户从链接导航到目标站点时允许发送 Cookie。
- None:浏览器将不会阻止第三方网站对 Cookie 的访问,但必须与 Secure 属性一起使用(即,只能通过 HTTPS 传输)。
这些属性可以单独或组合使用,以创建具有所需行为和安全性的 Cookie。
五、域属性空间范围
在JavaWeb编程的API中,存在三个可以存放域属性的空间范围对象,这三个对象中锁存储的域属性作用范围,由大到小分别为:
- ServletContext:即application,置入其中的域属性是整个应用范围,可以完成跨会话共享数据。
- HttpSession:置入其中的域属性是会话范围的,可以完成跨请求共享数据。
- HttpServletRequest:置入其中的域属性是请求范围的,可以完成跨Servlet共享数据。但这些Servlet必须在同一个请求中。
对于这三个域属性空间对象的使用原则是,在可以保证功能需求的前提下,优先使用小范围。这样不仅可以节省服务器内存,还可以保证数据的安全性。
1、网站上次的访问时间
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CookieDemo01
* cookie实例:获取用户上一次访问的时间
*/
@WebServlet("/CookieDemo01")
public class CookieDemo01 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CookieDemo01() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Cookie[] cookies = request.getCookies();
if(cookies != null) {
out.write("您上次的访问时间是:");
for(int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if(cookie.getName().equals("lastAccessTime")) {
Long lastAccessTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastAccessTime);
out.write(date.toLocaleString());
}
}
}else {
out.write("这是您第一次访问本站!");
}
Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
response.addCookie(cookie);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
2、使用Cookie保存用户名和密码,当用户再次登录时,在相应的文本栏显示上次登录时的输入信息。
LoginServlet:
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String cookieName = "userName";
String cookiePwd = "pwd";
Cookie[] cookies = request.getCookies();
String userName = "";
String pwd = "";
String isChecked="";
if(cookies != null && cookies.length > 0) {
isChecked = "checked";
for(int i =0; i < cookies.length; i++) {
if(cookies[i].getName().equals(cookieName)) {
userName = cookies[i].getValue();
}
if(cookies[i].getName().equals(cookiePwd)) {
pwd = cookies[i].getValue();
}
}
}
response.setContentType("text/html;charset=GBK");
PrintWriter out = response.getWriter();
out.println("<html>\n");
out.println("<head><title>登录</title></head>");
out.println("<body>\n");
out.println("<center>\n");
out.println("<form action='CookieTest'"+"method='get'>");
out.println("姓名:<input type='text'"+"name='UserName' value='"+userName+"'><br/>\n");
out.println("密码:<input type='password' name='Pwd' value='"+pwd+"'><br/>\n");
out.println("保存用户名和密码<input type='checkbox'"+"name='SaveCookie' value='Yes'"+isChecked+">\n");
out.println("<br/>\n");
out.println("<input type='submit'>\n");
out.println("</form>\n");
out.println("</center>\n");
out.println("</body>\n");
out.println("</html>");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
CookieTest:
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CookieTest
*/
@WebServlet("/CookieTest")
public class CookieTest extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CookieTest() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
Cookie userCookie = new Cookie("userName",request.getParameter("UserName"));
Cookie pwdCookie = new Cookie("pwd",request.getParameter("Pwd"));
if(request.getParameter("SaveCookie") != null && request.getParameter("SaveCookie").equals("Yes")) {
userCookie.setMaxAge(7*24*60*60);
pwdCookie.setMaxAge(7*24*60*60);
} else {
userCookie.setMaxAge(0);
pwdCookie.setMaxAge(0);
}
response.addCookie(userCookie);
response.addCookie(pwdCookie);
PrintWriter out = response.getWriter();
out.println("Welcome,"+request.getParameter("UserName"));
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Learning-JavaWeb</display-name>
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>cookieTest</servlet-name>
<servlet-class>servlet.CookieTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cookieTest</servlet-name>
<url-pattern>/cookieTest</url-pattern>
</servlet-mapping>
</web-app>