一篇文章徹底搞懂 Cookie !
Cookie是什么
cookie的中文翻譯是曲奇,小甜餅的意思。cookie其實(shí)就是一些數(shù)據(jù)信息,類型為“小型文本文件”,存儲(chǔ)于電腦上的文本文件中。
Cookie有什么用
我們想象一個(gè)場(chǎng)景,當(dāng)我們打開一個(gè)網(wǎng)站時(shí),如果這個(gè)網(wǎng)站我們?cè)?jīng)登錄過(guò),那么當(dāng)我們?cè)俅未蜷_網(wǎng)站時(shí),發(fā)現(xiàn)就不需要再次登錄了,而是直接進(jìn)入了首頁(yè)。例如bilibili,csdn等網(wǎng)站。
這是怎么做到的呢?其實(shí)就是游覽器保存了我們的cookie,里面記錄了一些信息,當(dāng)然,這些cookie是服務(wù)器創(chuàng)建后返回給游覽器的。游覽器只進(jìn)行了保存。下面展示bilibili網(wǎng)站保存的cookie。

Cookie的表示
一般情況下,cookie是以鍵值對(duì)進(jìn)行表示的(key-value),例如name=jack,這個(gè)就表示cookie的名字是name,cookie攜帶的值是jack。
Cookie的組成
下面我自己寫了一個(gè)簡(jiǎn)易Servlet來(lái)設(shè)置cookie,我們游覽器抓包進(jìn)行查看。然后進(jìn)行分析

以下是cookie中常用屬性的解釋。
Name:這個(gè)是cookie的名字
Value:這個(gè)是cooke的值
Path:這個(gè)定義了Web站點(diǎn)上可以訪問(wèn)該Cookie的目錄
Expires:這個(gè)值表示cookie的過(guò)期時(shí)間,也就是有效值,cookie在這個(gè)值之前都有效。
Size:這個(gè)表示cookie的大小
想要完全了解所有cookie屬性,請(qǐng)參考百度知道:cookie
Cookie的HTTP傳輸
我們還是通過(guò)抓包進(jìn)行查看。首先查看cookie在HTTP請(qǐng)求中是怎樣進(jìn)行表示的。
HTTP請(qǐng)求

我們?cè)诎l(fā)送HTTP請(qǐng)求時(shí),發(fā)現(xiàn)游覽器將我們的cookie都進(jìn)行了攜帶(注意:游覽器只會(huì)攜帶在當(dāng)前請(qǐng)求的url中包含了該cookie中path值的cookie),并且是以key:value的形式進(jìn)行表示的。多個(gè)cookie用;進(jìn)行隔開。
我們?cè)賮?lái)查看cookie在HTTP響應(yīng)中是如何進(jìn)行表示的。
HTTP響應(yīng)

我在服務(wù)器設(shè)置了2個(gè)cookie,返回給游覽器。通過(guò)抓包,我們發(fā)現(xiàn)在HTTP響應(yīng)中, cookie的表示形式是,Set-Cookie:cookie的名字,cookie的值。如果有多個(gè)cookie,那么在HTTP響應(yīng)中就使用多個(gè)Set-Cookie進(jìn)行表示。
Cookie的生命周期
cookie有2種存儲(chǔ)方式,一種是會(huì)話性,一種是持久性。
會(huì)話性:如果cookie為會(huì)話性,那么cookie僅會(huì)保存在客戶端的內(nèi)存中,當(dāng)我們關(guān)閉客服端時(shí)cookie也就失效了
持久性:如果cookie為持久性,那么cookie會(huì)保存在用戶的硬盤中,直至生存期結(jié)束或者用戶主動(dòng)將其銷毀。
cookie我們是可以進(jìn)行設(shè)置的,我們可以人為設(shè)置cookie的有效時(shí)間,什么時(shí)候創(chuàng)建,什么時(shí)候銷毀。
Cookie使用的常見(jiàn)方法
下面,我對(duì)java中Cookie對(duì)象的方法進(jìn)行講解
new Cookie(String name, String value):創(chuàng)建一個(gè)Cookie對(duì)象,必須傳入cookie的名字和cookie的值
getValue():得到cookie保存的值
getName():獲取cookie的名字
setMaxAge(int expiry):設(shè)置cookie的有效期,默認(rèn)為-1。這個(gè)如果設(shè)置負(fù)數(shù),表示客服端關(guān)閉,cookie就會(huì)刪除。0表示馬上刪除。正數(shù)表示有效時(shí)間,單位是秒。
setPath(String uri):設(shè)置cookie的作用域
HttpServletRequest和HttpServletResponse對(duì)Cookie進(jìn)行操作的常見(jiàn)方法
response.addCookie(Cookie cookie):將cookie給客戶端進(jìn)行保存
resquest.getCookies():得到客服端傳過(guò)來(lái)的所有cookie對(duì)象
Cookie應(yīng)用實(shí)例
我們使用cookie來(lái)實(shí)現(xiàn)一個(gè)功能,就是當(dāng)用戶登錄成功后,我們?cè)谙麓蔚卿洉r(shí)就自動(dòng)填入用戶名和密碼。這個(gè)功能我們使用cookie和jsp頁(yè)面來(lái)完成(用html頁(yè)面也可以,只不過(guò)要使用javascript,有點(diǎn)麻煩,所以就使用jsp進(jìn)行演示)
我們首先寫一個(gè)簡(jiǎn)單的jsp頁(yè)面,就是一個(gè)登錄頁(yè)面
JSP頁(yè)面
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>登錄</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/main" method="post">
用戶名:<input type="text" name="username" value="<%=request.getAttribute("username")%>"><br/>
密 碼:<input type="password" name="password" value="<%=request.getAttribute("password")%>"><br/>
<input type="submit" value="登錄">
</form>
</body>
</html>
請(qǐng)求轉(zhuǎn)發(fā)頁(yè)面,我們是通過(guò)訪問(wèn)Servlet轉(zhuǎn)發(fā)到j(luò)sp頁(yè)面的,而不是直接訪問(wèn)。
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/cookieLogin")
public class CookieLogin extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//設(shè)置默認(rèn)值
request.setAttribute("username","");
request.setAttribute("password","");
//得到所有cookie
Cookie[] cookies = request.getCookies();
//對(duì)所有cookie進(jìn)行遍歷
for (Cookie cookie : cookies) {
//得到存儲(chǔ)用戶名和密碼的cookie并且存入request域中
if ("username".equals(cookie.getName())){
String value = cookie.getValue();
request.setAttribute("username",value);
}
if("password".equals(cookie.getName())){
String value = cookie.getValue();
request.setAttribute("password",value);
}
}
//轉(zhuǎn)發(fā)到login.jsp頁(yè)面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
登錄成功后的首頁(yè)
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/main")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//設(shè)置響應(yīng)類型
response.setContentType("text/html;charset=utf-8");
//得到用戶名和密碼
String username = request.getParameter("username");
String password = request.getParameter("password");
//判斷是否登錄成功
if ("root".equals(username) && "root".equals(password)) {
//編寫cookie
Cookie usernameCookie = new Cookie("username", username);
Cookie passwordCookie = new Cookie("password", password);
//設(shè)置有效時(shí)間,我這里設(shè)置3天有效
usernameCookie.setMaxAge(60 * 60 * 24 * 3);
passwordCookie.setMaxAge(60 * 60 * 24 * 3);
//存入客戶端
response.addCookie(usernameCookie);
response.addCookie(passwordCookie);
//返回提示
response.getWriter().write("<h1>登錄成功~~~~</h1>");
}else {
response.getWriter().write("<h1>登錄失敗....</h1>");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
下面我們來(lái)進(jìn)行測(cè)試一下,首先訪問(wèn)http://localhost:8080/cs/cookieLogin,我們這里設(shè)置的虛擬路徑是cs,下面是我們?cè)L問(wèn)cookieLogin顯示的頁(yè)面。發(fā)現(xiàn)確實(shí)沒(méi)有自動(dòng)填寫,因?yàn)槲覀冞€沒(méi)有登錄。瀏覽器中也沒(méi)有存有用戶名和密碼的cookie


輸入正確的賬號(hào)和密碼進(jìn)行登錄。也就是賬號(hào)和密碼都輸入root,頁(yè)面顯示登錄成功

下面我們來(lái)查看游覽器是否存儲(chǔ)了用戶名和密碼的cookie

游覽器確實(shí)存儲(chǔ)了cookie,沒(méi)有問(wèn)題,接下來(lái),我們關(guān)閉游覽器后重新訪問(wèn)登錄頁(yè)面。

我們一訪問(wèn)登錄頁(yè)面,用戶名和密碼就自動(dòng)填寫了,成功實(shí)現(xiàn)了功能
總結(jié)
Cookie就是一些數(shù)據(jù),用于存儲(chǔ)服務(wù)器返回給客服端的信息,客戶端進(jìn)行保存。在下一次訪問(wèn)該網(wǎng)站時(shí),客戶端會(huì)將保存的cookie一同發(fā)給服務(wù)器,服務(wù)器再利用cookie進(jìn)行一些操作。利用cookie我們就可以實(shí)現(xiàn)自動(dòng)登錄,保存游覽歷史,身份驗(yàn)證等功能。
作者:禿頭披風(fēng)俠
鏈接:https://blog.csdn.net/m0_51545690/article/details/123359959

往期推薦
