Cookie 與 Session概述

????????在 Web 開發中,會話跟蹤是一個核心問題。HTTP 協議是無狀態的,這意味著服務器無法直接記住客戶端的狀態。而 Cookie 和 Session 技術的出現,正是為了解決這一難題。

一、Cookie概述

????????Cookie,翻譯成中文是小甜點、小餅干的意思。在 HTTP 協議中,它代表著服務器送給客戶端瀏覽器的 “小甜點”。實際上,Cookie 就是由一個鍵和一個值構成的信息,會隨著服務器端的響應發送給客戶端瀏覽器。客戶端瀏覽器會將其保存起來,等下一次訪問該服務器時,再把 Cookie 發送回服務器。

Cookie 的規范

不用擔心 Cookie 會占滿你的硬盤,因為它有嚴格的規范限制:

  • 一個 Cookie 最多只有 4KB 大小。
  • 瀏覽器最多可以保存 300 個 Cookie。

????????不過,在瀏覽器競爭的大環境下,一些瀏覽器對 Cookie 規范進行了 “擴展”,比如有的瀏覽器允許每個 Cookie 為 8KB,最多可保存 500 個 Cookie,但即便如此,也不會出現占滿硬盤的情況。另外,不同的瀏覽器之間是不能共享 Cookie 的。

Cookie 的作用

????????Cookie 的核心作用就是 “跟蹤客戶端狀態”。服務器把信息保存在客戶端,客戶端下次請求時再把這些信息還給服務器,服務器就能通過這些信息識別客戶端了。

Cookie 的基本操作

  1. 保存 Cookie 到客戶端:這是響應工作的一部分,通過 HttpServletResponse 類的void addCookie(Cookie c)方法來實現,該方法可多次調用以添加多個 Cookie。例如:
Cookie cookie = new Cookie("username", "txjava");
response.addCookie(cookie);

????????這樣,在響應頭中就會添加 Set - Cookie 的值,客戶端瀏覽器也會保存該 Cookie。當下一次訪問服務器時,請求頭中就會帶著這個 Cookie 的值。

  1. 服務器端讀取 Cookie:瀏覽器保存 Cookie 后,會在下次請求時把 Cookie 放到請求頭中發送給服務器,服務器可通過 HttpServletRequest 的Cookie[] getCookies()方法讀取。示例如下:
Cookie[] cookies = request.getCookies();
if(cookies != null){for(Cookie cookie : cookies){System.out.println(cookie.getName() +":"+ cookie.getValue());}
}

Cookie 的生命周期

????????Cookie 的存活時間取決于其生命周期設置,默認情況下,Cookie 只在瀏覽器內存中存活,關閉瀏覽器后就會消失。可通過Cookie#setMaxAge(int expiry)方法設置存活時間(參數為秒數):

  • cookie.setMaxAge(60*60*24*30*12):表示 Cookie 可存活 1 小時(此處原文檔描述有誤,60*60 才是 1 小時),此時瀏覽器不僅會把 Cookie 保存在內存中,還會保存到硬盤上,即便關閉瀏覽器、重啟電腦,Cookie 也會存在 1 小時。
  • cookie.setMaxAge(-1):這是默認值(其實只要是負數都一樣),表示 Cookie 只在瀏覽器內存中存活,關閉瀏覽器窗口后就會消失。
  • cookie.setMaxAge(0):表示 Cookie 被作廢,既不在內存中存活,也不在硬盤上存活,目的是覆蓋客戶端原來的該 Cookie 使其失效。

Cookie 的路徑

????????Cookie 有一個 path 屬性,可通過Cookie#setPath(String)方法設置。若不設置,其默認路徑就是請求的路徑。比如請求http://localhost:8080/cookie_demo/path時,服務器響應的 Cookie 默認路徑是/cookie_demo;請求http://localhost:8080/cookie_demo/path/son時,默認路徑是/cookie_demo/path

Cookie 路徑的作用是決定服務器的請求是否會從瀏覽器中加載某些 Cookie。例如,有兩個 Cookie:

  • cookie1:name=path1;value=pathvalue1;path=/cookie_demo
  • cookie2:name=path1;value=pathvalue2;path=/cookie_demo/path

????????當訪問http://localhost:8080/cookie_demo/*時,請求頭中會包含 cookie1,不包含 cookie2;當訪問http://localhost:8080/cookie_demo/path/*時,請求頭中會包含 cookie1 和 cookie2。也就是說,訪問子路徑時會包含父路徑的 Cookie,訪問父路徑時不包含子路徑的 Cookie。

????????若想在 BServlet 中設置的 Cookie,在客戶端訪問 AServlet 時也能包含在請求頭中,可設置 BServlet 中 Cookie 的 path,如c2.setPath(“/cookie_demo”)(硬編碼)或c2.setPath(request.getContextPath() + “/”)(活編碼)。

Cookie 保存中文

????????Cookie 中不能直接設置中文,但可先使用URLEncoder.encode()方法編碼后再存放,獲取時先使用URLDecoder.decode()方法解碼。

  • 添加 Cookie:
Cookie cookie1 = new Cookie("username", URLEncoder.encode(username,"UTF-8"));
  • 讀取 Cookie:
Cookie[] cookies = request.getCookies();
if(cookies != null){for(Cookie cookie : cookies){if(cookie.getName().equals("username"))username = URLDecoder.decode(cookie.getValue(),"UTF-8");if(cookie.getName().equals("password"))password = cookie.getValue();}
}

Cookie 的瀏覽器管理

  1. Google Chrome:查看 Cookie 可通過相關入口操作;清理 Cookie 則在設置 - 隱私設置和安全性 - 清除瀏覽數據中進行。
  2. Firefox:查看 Cookie 有相應的操作入口;清理 Cookie 在選項 - 隱私與安全 - Cookie 和網站數據 - 清除數據中進行。

Cookie 的禁用

????????默認情況下瀏覽器啟用 Cookie,手動禁用后,絕大多數互聯網網站無法登錄,這與后續要講的 session 有關。判斷瀏覽器是否禁用 Cookie,可通過嘗試獲取剛剛添加的 Cookie,若獲取不到,則說明 Cookie 被禁用。

二、HttpSession:服務器端的會話對象

HttpSession 概述

????????Session 也是域對象之一,其范圍在一個會話范圍內有效,擁有getAttribute()setAttribute()等系列方法。在一個會話內共享一個 session 對象,可保存會話內的數據,如當前用戶的信息。

目前所學域對象的作用范圍:ServletContext > HttpSession > HttpServletRequest。

????????獲取 session 對象可使用request.getSession()方法。有了 session,就無需再用 Cookie 跟蹤會話,但 session 的生命周期相對較短,用戶關閉瀏覽器窗口后,session 就會失效。

HttpSession 原理(依賴 Cookie)

HTTP 是無狀態協議,但 session 能跟蹤會話狀態,這是因為 session 依賴 Cookie。

  • 客戶端第一次訪問服務器時,服務器會為其創建一個 session 對象,放入 session 池中,并在響應時通過 Cookie 將 sessionId 發送給客戶端。只有第一次訪問時,服務器才會創建 session 并響應 sessionId。
  • 客戶端再次訪問服務器時,會在請求中帶著 sessionId,服務器通過 sessionId 到 session 池中找到對應的 session 對象,從而完成會話跟蹤。服務器端保存 session 對象,客戶端只保存 sessionId,用戶在 session 中保存的數據就能被再次使用。

發送 sessionId 的 Cookie 的 maxAge 為 - 1,即只在瀏覽器內存中存在,關閉所有瀏覽器窗口后,該 Cookie 就會消失。

HttpSession 失效

session 失效主要有以下幾個原因:

  1. 調用session.invalidate()方法注銷 session。
  2. session 超時,可在配置中設置,如:
<session-config><!-- session的超時時間,以分鐘為單位 --><session-timeout>1</session-timeout>
</session-config>
  1. Cookie 被禁用,因為 session 依賴 Cookie 傳遞 sessionId,Cookie 禁用后,session 也會失效(不過可通過其他方式實現,如在 url 中傳遞 session_id)。

三、Session 和 Cookie 的區別(面試常考)

區別SessionCookie
存儲位置服務器端客戶端(瀏覽器)
存儲位置默認存在服務器的一個文件里(不是內存)客戶端瀏覽器中
運行依賴依賴 session id,而 session id 通常存在 cookie 中不依賴其他存儲對象
存儲位置可放在文件、數據庫、內存中存于客戶端瀏覽器
應用場景常用于用戶驗證等場合用于跟蹤客戶端狀態,如保存用戶偏好設置等

四、綜合練習:使用 cookie 實現自動登陸

實現思路

通過在客戶端保存包含用戶名和密碼信息的 Cookie,當用戶再次訪問時,服務器讀取 Cookie 中的信息進行自動登錄驗證。

代碼實現

  1. html 代碼
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="login" method="post">用戶:<input type="text" name="username"/><br><br>密碼:<input type="password" name="password"/><br><br><input type="checkbox" value="1" name="auto"/>&nbsp;一天內自動登陸<br><br><input type="submit" value="登陸"/><br>
</form>
</body>
</html>
  1. Java 代碼
package cn.tx.servlet;import cn.tx.model.User;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;/*** 模擬自動登陸方法*/
@WebServlet(name = "LoginServlet",urlPatterns = "/login")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 獲取用戶端提交的表單信息String username = request.getParameter("username");String password = request.getParameter("password");String auto = request.getParameter("auto");// 統一設置response響應格式及編碼response.setContentType("text/html;charset=utf-8");response.setCharacterEncoding("UTF-8");// 判斷是否提交用戶信息if(username == null && password == null && auto == null){// 用來接收cookie的value信息String cookieValue = null;// 獲取用戶端cookiesCookie[] cookies = request.getCookies();// 如果cookies不為null  嘗試獲取name為txjavac的cookie的valueif(cookies != null){for(Cookie ck : cookies){if(ck.getName().equals("txjavac")){cookieValue = ck.getValue();}}}// 如果沒有獲取到cookie的value 返回信息if(cookieValue == null){response.getWriter().write("您還未進行登陸,請進行登陸!!!");return;}else{// 如果獲取到// 對該信息進行解碼BASE64Decoder decoder = new BASE64Decoder();cookieValue = new String(decoder.decodeBuffer(cookieValue));// 對解碼后的字符串進行切分String[] split = cookieValue.split(":");// 獲取用戶名和密碼username = split[1];password = split[2];// 創建用戶對象User user = new User(username,password);// 獲取sessionHttpSession session = request.getSession();// 把用戶對象存儲到session中session.setAttribute("user",user);// 返回內容response.getWriter().write("尊敬的"+username+",歡迎您!!!");return;}}// 判斷用戶名或密碼是否正確if(username!=null && password!=null && username.equals("admin") && password.equals("txjava")){// 創建用戶對象User user = new User(username,password);// 獲取session會話對象HttpSession session = request.getSession();// 把用戶存入session中session.setAttribute("user",user);// 用戶名密碼正確的話,判斷是否勾選了一天內自動登陸if(auto != null && auto.equals("1")){// 拼接存儲于cookie的value值String value = "txjava:" + username + ":" + password + ":" + 24*3600;// 進行BASE64編碼BASE64Encoder encoder = new BASE64Encoder();value = encoder.encode(value.getBytes());// 創建cookie并且設置一天失效后添加到responseCookie cookie = new Cookie("txjavac",value);cookie.setMaxAge(24*3600);response.addCookie(cookie);}response.getWriter().write("尊敬的"+username+",歡迎您!!!");return;}else {response.getWriter().write("用戶名或密碼錯誤!!!");return;}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request,response);}
}

五、學習目標回顧

  • 熟練掌握 Cookie 的概念、使用及生命周期。
  • 能夠使用 Cookie 存儲中文并了解 Cookie 的路徑作用。
  • 掌握 Session 的原理及使用方法。
  • 能夠詳細說明 Cookie 和 Session 的區別。
  • 能夠獨立完成自動登陸功能的開發。

????????通過以上內容,相信大家對 Cookie 和 Session 有了較為全面的認識,在實際開發中,可根據具體需求靈活運用這兩種技術來實現會話跟蹤等功能

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/89556.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/89556.shtml
英文地址,請注明出處:http://en.pswp.cn/web/89556.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

阿里云alicloud liunux3-安裝docker

你這個錯誤&#xff1a;Curl error (35): SSL connect error for https://download.docker.com/linux/centos/8/x86_64/stable/... Error: Failed to download metadata for repo docker-ce-stable: Yum repo downloading error說明你的機器訪問 download.docker.com 的 HTTPS …

【世紀龍科技】汽車故障診斷與排除仿真教學軟件

在汽車產業智能化、電動化轉型加速的今天&#xff0c;汽車維修行業對技術人才的要求已從傳統經驗型向“理論實踐數字化”復合型轉變。然而&#xff0c;實車實訓成本高、安全隱患大、教學場景受限等問題&#xff0c;始終制約著職業教育的高質量發展。江蘇世紀龍科技有限公司立足…

柴油機活塞cad【4張】三維圖+設計說明書

1015柴油機活塞結構設計及溫度場分析 摘 要 隨著科研的進步&#xff0c;內燃機技術得到了快速的發展&#xff0c;低排放高效率的內燃機的發展成為內燃機發展的主要趨勢&#xff0c;活塞作為內燃機的主要組成部件&#xff0c;在內燃機中扮演著至關重要的作用。活塞在內燃機中始終…

雪豹大模型驅動效率革命 華鼎冷鏈科技重構餐飲供應鏈神經網絡

當餐飲行業的開店率高達67.5%、閉店率達61.2%時&#xff0c;供應鏈該如何進行革新與升級&#xff1f; 在鄭州盛大啟幕的第三屆中國火鍋燒烤領潮峰會上&#xff0c;華鼎冷鏈科技CEO王君以“AI驅動智慧供應鏈賦能餐飲行業新升級”為主題分享時稱&#xff0c;當前餐飲行業高閉店率…

汽車功能安全 -- TC3xx外部看門狗

之前聊過TC3xx SMU關于內部看門狗&#xff08;CPU Watchdog 和Safety Watchdog&#xff09;Alarm的處理方法。 汽車功能安全--TC3xx SMU之看門狗alarm處理 在里面我們提到了這些Alarm關聯的功能安全機制&#xff1a; SM[HW]:SCU:ENDINIT_WATCHDOG SM[HW]:SCU:SAFETY_WATCHD…

如何為“地方升學導向型”語校建模?Prompt 框架下的宇都宮日建工科專門學校解析(7 / 500)

如何為“地方升學導向型”語校建模&#xff1f;Prompt 框架下的宇都宮日建工科專門學校解析&#xff08;7 / 500&#xff09; 系列說明 500 所日本語言學校結構化建模實戰&#xff0c;第 7 篇。每篇拆解 1 所學校在 Prompt-QA 系統中的建模策略&#xff0c;分享工程經驗&#x…

Flutter 入門指南:從基礎到實戰

介紹 Flutter Flutter 是 Google 開發的開源移動應用軟件開發工具包&#xff08;SDK&#xff09;&#xff0c;用于快速在 iOS 和 Android 上構建高質量的原生界面。Flutter 的一大特點是其跨平臺功能&#xff0c;讓開發者能夠使用同一套代碼基礎為兩個平臺構建應用。這一點通過…

八字命理:梟印奪食的形成原理與解決辦法

梟印奪食(|)含義:原局食神傷官為喜用&#xff0c;印為忌正印/偏印克制了食神/傷官&#xff0c;克制形式可以是蓋頭/截腳/同在天干或者地支時相克(2)表現癥狀:emo、敏感、好面子、不敢開口說話、被環境壓制(3)癥狀剖析:印為忌&#xff1d;他人即地獄&#xff0c;不論正印(吉神)還…

數組和對象的深拷貝和淺拷貝的方法

數組和對象的深拷貝、淺拷貝方法有所不同&#xff0c;以下是常見的實現方式&#xff1a;一、淺拷貝方法&#xff08;數組和對象通用/專用&#xff09;淺拷貝只復制表層數據&#xff0c;嵌套的引用類型仍共享內存。1. 數組的淺拷貝- 擴展運算符&#xff08;...&#xff09;&…

【RK3576】【Android14】開發板概述

獲取更多相關的【RK3576】【Android14】驅動開發&#xff0c;可收藏系列博文&#xff0c;持續更新中&#xff1a; 【RK3576】Android 14 驅動開發實戰指南 1. 引言 RK3576處理器簡介&#xff1a; RK3576 是一顆高性能、低功耗的應用處理器芯片&#xff0c;專為ARM PC、邊緣計算…

凸優化課程學習筆記(一)

凸優化課程學習筆記(一) 課程:B站清華大學陳劍博士《凸優化基礎理論與應用》 優化理論概述 1. 優化序論 定義:凸優化是一門應用極為廣泛的學科,主要研究如何對決策問題進行最優選擇,探討最優解的性質,尋找高效的計算方法,并分析這些方法的理論基礎與實際應用表現。…

(四)OpenCV——特征點檢測與匹配

前言 特征點檢測與匹配是計算機視覺中的基礎技術&#xff0c;廣泛應用于圖像拼接、物體識別、三維重建、運動跟蹤等領域。OpenCV 提供了多種特征檢測與匹配算法的實現。 特征點檢測與匹配是計算機視覺中的核心技術&#xff0c;廣泛應用于多個領域。以下是其主要應用場景&…

if (a == 1 a == 2 a == 3)返回true的問題思考

引文&#xff1a; 無意中看到了這樣的非常規邏輯&#xff0c;在想前后端應該都可以實現&#xff0c;a 是變量&#xff0c;或者操作a時觸發了值得改變。 意義&#xff1a; 該問題讓我們知道了一切規則都是可以被打破的&#xff0c;世界上的規則都是為了解釋某種現象設計的。 題目…

MySQL的索引操作及底層結構淺析

一.索引提高數據庫的性能&#xff0c;索引是物美價廉的東西了。不用加內存&#xff0c;不用改程序&#xff0c;不用調sql&#xff0c;只要執行正確的 create index &#xff0c;查詢速度就可能提高成百上千倍。但是天下沒有免費的午餐&#xff0c;查詢速度的提高是以插入、更新…

stm32f4 dma的一些問題

文章目錄前言一、使用開發板燒錄dma代碼不生效問題二、一個工程同時使用uart2、uart3借助dma來傳遞1.并行。2.DMA "同時工作"的本質3.總線訪問的具體含義4.實際效果5.最佳實踐5.1 總線傳輸機制&#xff1a;6.DMA傳輸中斷的問題總結前言 記錄一些使用stm32f4 dma過程…

登錄功能實現深度解析:從會話管理到安全校驗全流程指南

登錄功能實現深度解析&#xff1a;從會話管理到安全校驗全流程指南大家好&#xff0c;我是凱哥Java本文標簽&#xff1a;登錄驗證流程、過濾器與攔截器、安全防護措施簡介本文深入探討了從登錄功能實現到會話管理和安全校驗的全流程&#xff0c;包括參數校驗、身份驗證、令牌生…

2023 年 5 月青少年軟編等考 C 語言六級真題解析

目錄 T1. 字符串插入 思路分析 T2. 機器翻譯 思路分析 T3. 棧基本操作 思路分析 T4. 雙端隊列 思路分析 T1. 字符串插入 題目鏈接:SOJ D1138 有兩個字符串 s t r str str 和 s u b s t r substr substr, s t r str str 的字符個數不超過 10 10 10, s u b s t r substr …

Redux架構解析:狀態管理的核心原理

Redux 作為 JavaScript 應用的狀態管理庫&#xff0c;其技術架構與核心原理圍繞??可預測的狀態管理??設計&#xff0c;通過嚴格的單向數據流和函數式編程理念實現復雜應用的狀態控制。以下從設計理念、核心架構、工作流程、源碼實現等角度進行系統性剖析&#xff1a;一、設…

linux制作鏡像、壓縮鏡像、燒錄的方法

最近在玩香橙派的時候&#xff0c;需要搞多個板子&#xff0c;一個一個配環境也太麻煩了吧......于是通過搜索&#xff0c;發現可以把linux設備&#xff08;比如香橙派&#xff0c;樹莓派等等&#xff09;制作為鏡像&#xff0c;然后像燒錄官方鏡像一樣燒進新的sd卡&#xff0c…

機械材料計算軟件,快速核算重量

軟件介紹 今天為大家推薦一款專為機械行業設計人員打造的金屬材料重量計算軟件&#xff0c;幫助工程師快速完成材料重量核算。 軟件特點 這款綠色版計算工具體積小巧&#xff0c;不足100KB&#xff0c;無需安裝即可直接運行&#xff0c;不占用系統資源&#xff0c;特別適…