“會話技術”——Cookie_(2/2)原理與使用細節

經過Cookie的快速入門與代碼使用。如果想深入理解Cookie的技術實現,就得去理解它的原理。
且有些時候使用Cookie,還要根據需求設置存活期限以及確定Cookie獲取范圍等其他細節。最后,我們會總結Cookie這門客戶端會話技術的作用。


一、原理

注:我們還是使用簡易圖畫進行輔助理解

注:這是上一節寫的代碼(兩個Servlet),這里將這個例子使用一下分析Cookie的原理

所謂分析Cookie原理,正是分析: 服務器端如何響應時發送Cookie,以至于瀏覽器端識別了還自動保存;并且CookieDemo2怎么獲取到的Cookie,即瀏覽器怎么就攜帶了Cookie信息進行了下一次請求。

1.1 分析:

?其實不管發送數據也好,還是獲取數據(站在服務器端看)也好,它們在客戶端與我端(服務端)中間都是以HTTP協議進行交互——響應和請求一定是遵循HTTP協議的

首先,客戶端發送了第一次請求,請求訪問了服務器端的資源——CookieDemo1。

CookieDemo1收到了請求,于是以“發送Cookie”進行處理數據并響應了(確實向瀏覽器發送了Cookie),剛剛說“所有的客戶與服務器端的響應請求都遵循HTTP協議”。所以那實際上,“發送Cookie”時,怎么發送呢? 服務器(response端)會在響應報文中設置一個名為“Set-Cookie”的響應頭,該響應頭的值以鍵值對的形式呈現,恰好可用于存儲Cookie

于是瀏覽器端會收到來自服務器端的響應報文,發現響應報文的響應頭有“set-Cookie”。瀏覽器因為熟讀HTTP協議,所以遵循協議:如果瀏覽器收到了set-Cookie響應頭,它應該將這個頭里攜帶的數據(“name=Bear”)保存到自己本地中。

而在第二次請求時,HTTP協議又規定了:瀏覽器應該在下一次請求中將保存的數據(“name=Bear”)放進一個Cookie的請求頭中(作為值)。瀏覽器端會在請求報文中設置一個Cookie請求頭,其值類型也為鍵值對,恰好也用來放Cookie數據。

?于是CookieDemo2能從請求頭中獲取到Cookie信息。但是,在咱們使用Cookie代碼獲取請求里的Cookie,并不是操作所謂的“Cookie這個請求頭”,而是怎么??

Cookie[] cookies = request.getCookies();
//這樣一個名叫getCookies()的方法

?這也得多虧了JAVA EE 內部實現的API,封裝的庫方法(函數)。讓我們調用里的方法就能發送和獲取Cookie,而方法便是去和請求頭或者響應頭打交道,我們放心調用就行。

1.2 看看:

初見"set-Cookie"響應頭和“Cookie”請求頭,不熟悉很正常,多看幾眼。我們在瀏覽器抓包

1.2.1抓包

(瀏覽器端)按F12鍵 ,接著如圖操作:

我們現在運行,訪問CookieDemo1—— :抓抓它的響應包:?

是吧,這發送Cookie響應時會真的有一個響應標頭Set-Cookie。

那如果我們繼續請求CookieDemo2:抓抓它的請求報文,是不是在存儲Cookie后下一次請求就會在請求頭里捎帶上Cookie數據。

確實是。?

?二、Cookie的細節

2.1?一次可不可以發送多個cookie呢?

了解了原理這個問題== 響應報文set-Cookie的值可以是多個鍵值對嗎??

我們修改修改CookieDemo1:

// 原
@WebServlet("/CookieServlet01")
public class CookieServlet01 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request,response);}protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{// 1. 創建Cookie,綁定數據Cookie cookie = new Cookie("name","Bear");// 2. 發送Cookie對象response.addCookie(cookie);}}

我們再創建一個Cookie,讓response調用兩次addCookie();

protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{// 1. 創建Cookie,綁定數據Cookie cookie = new Cookie("name","Bear");Cookie cookie2 = new Cookie("place","Toilet");//新建// 2. 發送Cookie對象response.addCookie(cookie);response.addCookie(cookie2);//連著發送}

運行這段代碼,即重新請求CookieDemo1,抓抓它的請求包:

答案:一次可以發送多個Cookie。

為了完整,我們再訪問打印Cookie的那個Servlet,抓抓這回的請求包:

都存了,是的,剛剛響應發來的Cookie都存進瀏覽器了;這會兒,也全部放進請求頭Cookie了。

2.2 Cookie在瀏覽器中能保存多長時間?

默認情況下,當瀏覽器關閉后,Cookie數據被銷毀;因為默認存到瀏覽器內存里,程序結束,內存就會刪除數據。

如果想設置持久化存儲,我們這里再學習一個Cookie的方法:

cookie.setMaxAge(int seconds)
//參數是int類型,單位為秒數。
// int 是有符號整型,于是根據取值的不同,該方法會實現不同的效果

?若seconds 為 正數 :意味著 a.?將Cookie數據寫到硬盤的文件中、持久化存儲。

b. 規定了該Cookie存活的時間

若seconds 為 0 : 意味著刪除該Cookie。設置完cookie的MaxAge,需要將這個Cookie發送給客戶端。

為什么秒數為0,就意味著刪除? 這句話看似只有1個問,其實有2個答案。
1. Cookie 最大存活期限為0,那么就意味著“不存在”。
2. Cookie是存在用戶端的數據,服務器端不能直接操作客戶端的數據,所以服務器想要刪除Cookie就用這種方式:設MaxAge=0,再響應發送。

若seconds為 負數:意味著默認設置(所以設為負數,跟不設置MaxAge效果一樣:一旦關閉瀏覽器,存在內存里的Cookie就會被釋放,失效)

代碼實踐timing :

我們新建一個CookieServlet03來創建和發送Cookie。

/** CookieDemo03 用來創建和發送Cookie* 分別設置存活期限:*  ^ 正數*  ^ 負數*  ^ 0* */
@WebServlet("/CookieServlet03")
public class CookieServlet03 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request,response);}protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{// 1. 創建Cookie,綁定數據// 2. 設置Cookie的存活期限// 3. 發送Cookie對象}
}

?寫入核心代碼:

        // 1. 創建Cookie,綁定數據Cookie cookie = new Cookie("name","bear");// 2. 設置Cookie的存活期限cookie.setMaxAge(30);//設置正數的存活期限,代表了:1.將Cookie數據寫到硬盤的文件中。持久化存儲。2.Cookie存活時間// 3. 發送Cookie對象response.addCookie(cookie);

?驗證邏輯:我們重新打開瀏覽器,先訪問CookieServlet03(客戶端收到cookie會存起來),再請求訪問CookieDemo02(這時可在Eclipse控制臺打印出Cookie信息)。

如果在30秒之內,我們關閉瀏覽器又訪問CookieServlet02,按理可以獲取并打印這個Cookie:

如果超過30秒后,我們再次訪問CookieServlet02,我們再看控制臺:

負數和0的取值,也是同樣驗證步驟。

?2.3?cookie能不能存中文?

在tomcat 8之前,不能存中文。

那怎么辦? 需要將中文數據轉碼 —— 一般采用URL編碼(如:%E3)

在tomcat 8之后 ,cookie支持中文數據,但還是不支持特殊字符。

我們現在使用的是tomcat 9,故tomcat8之前的不做演示。

運行服務器,訪問CookieServlet03,再訪問CookieServlet02打印:

以上驗證,tomcat8以上,Cookie能存中文。

2.4 cookie獲取范圍多大?

假設在一個服務器(也就是一個tomcat)中,部署了多個web項目,那么在這些web項目中cookie能不能共享?

圖:工程目錄下的項目們

經過作者的超絕不經意安排,有以下兩個項目:?

?它們的cookieDemo2和cookieServlet02都是獲取request的Cookies并打印。

這時我們驗證的問題:項目1下的cookieServlet01發送給客戶端的Cookie,會被項目2下的cookieDemo2獲取到嗎(即跨項目的cookie能獲得嗎)

項目1下的CookieServlet01

我們接下來就訪問這個Servlet:

接著我們訪問項目2下的cookieDemo2:?

?最后得到驗證:

假設在一個服務器中,部署了多個web項目,那么在這些web項目中cookie能不能共享?
默認情況下cookie不能共享

假如就有這個需求,需要一個服務器上多個項目共享Cookie,該如何呢?

2.4.2 多個項目共享Cookie

之所以Cookie多個項目不能共享,是因為默認情況下,客戶端存儲的Cookie目錄是以項目名為目錄的:

項目不同,項目名就不同。自然該目錄下就不會出現其他項目名的Cookie。

這里引入Cookie的另一個方法:

Cookie.setPath(String Path);
//參數為字符串類型,表示該cookie的存儲路徑。

?運行:

?此時若我們再訪問另一個項目下的打印Servlet:

?

再看控制臺,成功打印了項目1剛剛存的Cookie。

所以,想要實現一個服務器下多個項目下的Cookie共享:就setPath()。

2.4.3 多個服務器Cookie共享

其實還是同樣的道理,調用cookie方法,但是是不同的方法:

setDomain(String path)
// 參數:字符串類型,設置域名

如果設置一級域名相同,那么多個服務器之間的cookie可以共享
如果SetDomain(“.baidu.com”),那么tieba.baidu.com和news.baidu.com中cookie可以共享
因為這兩個服務器都是baidu管轄下的,那何必要設置兩個服務器呢?是因為如果一個服務器承受不了大量的用戶請求訪問。

比較淺顯的解釋,但這里簡單提出,僅為知識體系的完整。后面再次接觸的時候就會深入應用。

三、Cookie的特點和作用:

特點:

1.?? ?cookie存儲數據在客戶端瀏覽器
2.?? ?瀏覽器對于單個cookie的大小有限制(4kb左右) 以及 對于同一個域名下的總cookie數量也有限制(20個)
這Cookie的名字也暗示了存不了多少數據。Cookie——“小甜點”,飯后甜食或者下午茶小點心,不能當主食。

?作用:

1.?? ?Cookie一般用于存儲少量的不太敏感的數據
2.?? ?在不登錄的情況下,完成服務器對客戶端的身份識別;而登錄的話,就是在數據庫里獲取數據

“不太敏感”,存在客戶端,咱們一抓包或者在“開發者工具”里就能看到,服務器這邊還能刪除……無不昭示著客戶端安全性不太高,盡量不存敏感數據。

?第二點還挺重要,需要好好理解:

我們來到baidu的主頁面:

我們在輸入框輸入問題:

?如果我們既不登錄,又想實現輸入問題的時候沒有自動聯想:

我們再次來到主頁面,此時還是未登錄狀態:

若我關閉瀏覽器,再次進入baidu,輸入問題也沒有自動聯想。為什么呢?是因為剛剛的“保存設置”時發出請求,baidu響應了這些設置,數據以set-Cookie標頭響應過來。

瀏覽器保存這些信息(Cookie),而我們再次來到baidu主頁面:我們的請求會自動攜帶Cookie。而baidu服務器則會獲取請求里的Cookie,再將我們的需求響應給我們。

這就是Cookie:在未登錄的狀態下?,服務器完成對客戶端身份的識別。如果登錄的話,服務器就直接在它的數據庫里提取數據了。


下一節:Cookie的實戰應用

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

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

相關文章

DBeaver連接人大金倉數據庫V9

1、官網下載驅動jdbc 打開官網地址,找到下面的V9R1-JDBC,點擊后面的下載即可,保存到本地 2、解壓最新版的驅動程序 3、把***_JDBC文件夾內的驅動程序復制到DBeaver安裝目錄下的plugins文件夾里 4、打開dbeaver程序,增加kingbase…

服務器丟包率測試保姆級教程:從Ping到網絡打流儀實戰

測試服務器丟包率是網絡性能診斷的重要環節,丟包通常由網絡擁塞、硬件故障、配置錯誤或線路質量差導致。以下是多種測試方法的詳細步驟和工具說明: 一、基礎工具測試(無需專業設備) 1. 使用 ping 命令 命令示例: bash…

n8n 使用 AI Agent 和 MCP 社區節點

n8n 使用 AI Agent 和 MCP 社區節點 0. 前提條件1. 創建一個 "在聊天消息時" 節點2. 創建一個 "AI Agent" 節點 0. 前提條件 請參考 n8n 安裝 n8n-nodes-mcp 社區節點 安裝 MCP 社區節點。 1. 創建一個 “在聊天消息時” 節點 單擊 “測試聊天”&#xf…

抱佛腳之學SSMSpringMVC數據綁定

綁定默認數據類型 綁定簡單數據類型 綁定POJO類型 綁定包裝POJO 復雜數據綁定 綁定數組 綁定集合

解決“‘mvn‘ 不是內部或外部命令,也不是可運行的程序”錯誤

一、問題描述 當我們在Windows上運行sqlrest 工具時,提示mvn 不是內部或外部命令,也不是可運行的程序的錯誤,導致無法安裝sqlrest工具,如下圖所示: 二、問題分析 從提示中我們不難看出是由于我們缺失了【maven】環境,導致無法啟動項目;我們只需要安裝【maven】環境即可解…

DeepSeek R1:強化學習范式的推理強化模型

定位與目標 DeepSeek R1 的推出并非 DeepSeek V3 的簡單迭代,而是一次在訓練范式上的大膽探索。與傳統大模型主要依靠監督微調(SFT)后進行強化學習不同,R1 將重點放在推理能力和行為對齊上,嘗試通過大規模強化學習直接激發模型的推理潛力。其目標是利用強化學習的反饋機制,…

變轉速振動信號分析處理與故障診斷算法模塊

變轉速振動信號分析處理與故障診斷算法模塊,作為信號處理算法工具箱的主要功能模塊,形成了以變轉速振動信號分析處理與故障診斷算法模塊的經典算法模型,可應用于各類關鍵機械部件(軸承、齒輪、轉子等)的信號分析、故障…

Kafka 配置參數性能調優建議

文章目錄 1、生產者調優batch.size(重要)linger.mscompression.typeacks(重要)buffer.memorymax.in.flight.requests.per.connection(重要)message.max.bytes(重要) 2、消費者調優fe…

Redis怎么避免熱點數據問題

使用 RedisTemplate 避免熱點數據問題的解決方案、場景及示例: 1. 數據分片(Sharding) 場景:高頻讀寫的計數器(如文章閱讀量統計) ?原理?:將數據分散到多個子鍵,降低單個 Key 的壓…

B站Michale_ee——ESP32_IDF SDK——FreeRTOS_8 消息緩沖區

Message Buffer(消息緩沖區)與Stream Buffer(流數據緩沖區)類似,但有2點不同: Message Buffer每次只接收1次完整的Message;Message Buffer接收緩沖區小于1條Message大小時,會接收不到數據&#…

【計算機網絡網絡層深度解析】從IP協議到路由優化

目錄 前言技術背景與價值當前技術痛點解決方案概述目標讀者說明 一、技術原理剖析核心概念圖解核心作用講解關鍵技術模塊說明技術選型對比 二、實戰演示環境配置要求核心實驗實現實驗1:IPv6地址配置實驗2:OSPF路由配置實驗3:NAT轉換驗證 運行…

【Hive入門】Hive性能調優:小文件問題與動態分區合并策略詳解

目錄 引言 1 Hive小文件問題概述 1.1 什么是小文件問題 1.2 小文件產生的原因 2 Hive小文件合并機制 2.1 hive.merge.smallfiles參數詳解 2.2 小文件合并流程 2.3 合并策略選擇 3 動態分區與小文件問題 3.1 動態分區原理 3.2 動態分區合并策略 3.3 動態分區合并流程…

如何讓Steam下載速度解除封印?!

平時一直沒注意到家里的路由器在偷懶。最近成功榨干家里的帶寬,把平時一直20mb/s左右下載速度的路由器一番改造后成功steam下載速度穩定85Mb/s。平時一直都只發揮了他的1/3不到,真是太可惜了。 硬件 首先檢查硬件,就千兆路由器而言&#xf…

通信原理第七版與第六版的區別附pdf

介紹 我用夸克網盤分享了「通信原理 第7版》樊昌信」, 鏈接:https://pan.quark.cn/s/be7c5af4cdce 《通信原理(第7版)》是在第6版的基礎上,為了適應當前通信技術發展和教學需求,并吸取了數十所院校教師的反…

【2025五一數學建模競賽A題】 支路車流量推測問題|建模過程+完整代碼論文全解全析

你是否在尋找數學建模比賽的突破點?數學建模進階思路! 作為經驗豐富的美賽O獎、國賽國一的數學建模團隊,我們將為你帶來本次數學建模競賽的全面解析。這個解決方案包不僅包括完整的代碼實現,還有詳盡的建模過程和解析&#xff0c…

Python爬蟲實戰:獲取彼岸網高清素材圖片

一、引言 在數字化時代,圖片素材的需求持續增長。彼岸網提供了豐富的高質量圖片資源,其中 4K 風景圖片備受用戶青睞。借助 Python 爬蟲技術,可自動化地從彼岸網獲取這些圖片,為用戶提供便捷的圖片素材服務。然而,爬取過程中會遭遇登錄驗證、反爬機制等問題,需采用相應技…

深入理解 C++ 數據類型:從基礎到高級應用

C 是一種強類型語言,這意味著每個變量都必須有明確的數據類型,以便編譯器知道如何存儲和操作數據。數據類型決定了變量的內存占用、取值范圍以及可以執行的操作。理解 C 的數據類型是編寫高效、安全代碼的基礎。本文將全面介紹 C 的數據類型,…

補題:K - Magic Tree (Gym - 105231K)

來源:問題 - K - Codeforceshttps://codeforces.com/gym/105231/problem/K 題目描述: 一、題目分析 本題給定一個2行m列的網格,從(1, 1)格子開始進行深度優先搜索,每個格子可到達至少一個邊相鄰的格子且不重復訪問,…

【Prometheus-OracleDB Exporter安裝配置指南,開機自啟】

目錄 1. 安裝Oracle Instant Client1.1 解壓安裝包1.2 創建運行時鏈接 2. 環境配置2.1 設置環境變量2.2 驗證配置 3. 安裝Oracle DB Exporter3.1 創建工作目錄3.2 解壓安裝包3.3 添加執行權限 4. 數據庫監控配置4.1 創建監控用戶(切換到Oracle所屬用戶) …

溯因推理思維——AI與思維模型【92】

一、定義 溯因推理思維模型是一種從結果出發,通過分析、推測和驗證,尋找導致該結果的可能原因的思維方式。它試圖在已知的現象或結果基礎上,逆向追溯可能的原因,構建合理的解釋框架,以理解事物的本質和內在機制。 二、由來 溯因推理的思想可以追溯到古希臘哲學家亞里士…