深入理解Cookie

j-kelly-brito-416262-unsplash.jpg

1. 前言

朋友問我cookie是什么,用來干什么的,可是我居然無法清楚明白簡短地向其闡述cookie,這不禁讓我陷入了沉思:為什么我無法解釋清楚,我對學習的方法產生了懷疑!在知乎上看到有人推薦使用費爾曼學習技巧,于是在重新學習cookie的過程中使用了該技巧來試驗,效果有待驗證!

在學習一個新的知識點前,我們應該明白自己的學習目標,要帶著疑問去學習,該小節(jié)須要了解:

  1. 什么是cookie,cookie的作用
  2. cookie的工作機制,即cookie是運作流程
  3. cookie的基本屬性(4個)以及我們如何使用cookie

2. 什么是cookie

HTTP協(xié)議本身是無狀態(tài)的。什么是無狀態(tài)呢,即服務器無法判斷用戶身份。Cookie實際上是一小段的文本信息(key-value格式)??蛻舳讼蚍掌靼l(fā)起請求,如果服務器需要記錄該用戶狀態(tài),就使用response向客戶端瀏覽器頒發(fā)一個Cookie??蛻舳藶g覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,以此來辨認用戶狀態(tài)。

打個比方,我們去銀行辦理儲蓄業(yè)務,第一次給你辦了張銀行卡,里面存放了身份證、密碼、手機等個人信息。當你下次再來這個銀行時,銀行機器能識別你的卡,從而能夠直接辦理業(yè)務。

3. cookie機制

當用戶第一次訪問并登陸一個網站的時候,cookie的設置以及發(fā)送會經歷以下4個步驟:

客戶端發(fā)送一個請求到服務器 --》 服務器發(fā)送一個HttpResponse響應到客戶端,其中包含Set-Cookie的頭部 --》 客戶端保存cookie,之后向服務器發(fā)送請求時,HttpRequest請求中會包含一個Cookie的頭部 --》服務器返回響應數據

image

為了探究這個過程,寫了代碼進行測試,如下:

我在doGet方法中,new了一個Cookie對象并將其加入到了HttpResponse對象中

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
        // 設置生命周期為MAX_VALUE
        cookie.setMaxAge(Integer.MAX_VALUE);
        resp.addCookie(cookie);
    }

瀏覽器輸入地址進行訪問,結果如圖所示:

image

可見Response Headers中包含Set-Cookie頭部,而Request Headers中包含了Cookie頭部。name和value正是上述設置的。

4. cookie屬性項

屬性項 屬性項介紹
NAME=VALUE 鍵值對,可以設置要保存的 Key/Value,注意這里的 NAME 不能和其他屬性項的名字一樣
Expires 過期時間,在設置的某個時間點后該 Cookie 就會失效
Domain 生成該 Cookie 的域名,如 domain="www.baidu.com"
Path 該 Cookie 是在當前的哪個路徑下生成的,如 path=/wp-admin/
Secure 如果設置了這個屬性,那么只會在 SSH 連接時才會回傳該 Cookie

Expires

該屬性用來設置Cookie的有效期。Cookie中的maxAge用來表示該屬性,單位為秒。Cookie中通過getMaxAge()和setMaxAge(int maxAge)來讀寫該屬性。maxAge有3種值,分別為正數,負數和0。

如果maxAge屬性為正數,則表示該Cookie會在maxAge秒之后自動失效。瀏覽器會將maxAge為正數的Cookie持久化,即寫到對應的Cookie文件中(每個瀏覽器存儲的位置不一致)。無論客戶關閉了瀏覽器還是電腦,只要還在maxAge秒之前,登錄網站時該Cookie仍然有效。下面代碼中的Cookie信息將永遠有效。

        Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
        // 設置生命周期為MAX_VALUE,永久有效
        cookie.setMaxAge(Integer.MAX_VALUE);
        resp.addCookie(cookie);

當maxAge屬性為負數,則表示該Cookie只是一個臨時Cookie,不會被持久化,僅在本瀏覽器窗口或者本窗口打開的子窗口中有效,關閉瀏覽器后該Cookie立即失效。

        Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
        // MaxAge為負數,是一個臨時Cookie,不會持久化
        cookie.setMaxAge(-1);
        resp.addCookie(cookie);

可以看到,當MaxAge為-1時,時間已經過期

image

當maxAge為0時,表示立即刪除Cookie

        Cookie[] cookies = req.getCookies();
        Cookie cookie = null;

        // get Cookie
        for (Cookie ck : cookies) {

            if ("mcrwayfun".equals(ck.getName())) {
                cookie = ck;
                break;
            }
        }

        if (null != cookie) {
            // 刪除一個cookie
            cookie.setMaxAge(0);
            resp.addCookie(cookie);
        }

那么maxAge設置為負值和0到底有什么區(qū)別呢?

maxAge設置為0表示立即刪除該Cookie,如果在debug的模式下,執(zhí)行上述方法,可以看見cookie立即被刪除了。

image

maxAge設置為負數,能看到Expires屬性改變了,但Cookie仍然會存在一段時間直到關閉瀏覽器或者重新打開瀏覽器。

image

修改或者刪除Cookie

HttpServletResponse提供的Cookie操作只有一個addCookie(Cookie cookie),所以想要修改Cookie只能使用一個同名的Cookie來覆蓋原先的Cookie。如果要刪除某個Cookie,則只需要新建一個同名的Cookie,并將maxAge設置為0,并覆蓋原來的Cookie即可。

新建的Cookie,除了value、maxAge之外的屬性,比如name、path、domain都必須與原來的一致才能達到修改或者刪除的效果。否則,瀏覽器將視為兩個不同的Cookie不予覆蓋。

值得注意的是,從客戶端讀取Cookie時,包括maxAge在內的其他屬性都是不可讀的,也不會被提交。瀏覽器提交Cookie時只會提交name和value屬性,maxAge屬性只被瀏覽器用來判斷Cookie是否過期,而不能用服務端來判斷。

image

我們無法在服務端通過cookie.getMaxAge()來判斷該cookie是否過期,maxAge只是一個只讀屬性,值永遠為-1。當cookie過期時,瀏覽器在與后臺交互時會自動篩選過期cookie,過期了的cookie就不會被攜帶了。

Cookie的域名

Cookie是不可以跨域名的,隱私安全機制禁止網站非法獲取其他網站的Cookie。

正常情況下,同一個一級域名下的兩個二級域名也不能交互使用Cookie,比如test1.mcrwayfun.com和test2.mcrwayfun.com,因為二者的域名不完全相同。如果想要mcrwayfun.com名下的二級域名都可以使用該Cookie,需要設置Cookie的domain參數為.mcrwayfun.com,這樣使用test1.mcrwayfun.com和test2.mcrwayfun.com就能訪問同一個cookie

一級域名又稱為頂級域名,一般由字符串+后綴組成。熟悉的一級域名有baidu.com,qq.com。com,cn,net等均是常見的后綴。
二級域名是在一級域名下衍生的,比如有個一級域名為mcrfun.com,則blog.mcrfun.comwww.mcrfun.com均是其衍生出來的二級域名。

Cookie的路徑

path屬性決定允許訪問Cookie的路徑。比如,設置為"/"表示允許所有路徑都可以使用Cookie

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 目錄Cookie機制什么是CookieCookie的不可跨域名性Unicode編碼:保存中文BASE64編碼:保存...
    Tomatoro閱讀 17,041評論 7 186
  • 會話(Session)跟蹤是Web程序中常用的技術,用來跟蹤用戶的整個會話。常用的會話跟蹤技術是Cookie與Se...
    chinariver閱讀 5,778評論 1 49
  • Cookie技術是客戶端的解決方案,Cookie就是由服務器發(fā)給客戶端的特殊信息,而這些信息以文本文件的方式存放在...
    饑人谷_陸邈閱讀 1,666評論 1 5
  • server:本demo開發(fā)工具采用springSTS前提讀寫分離庫已經搭建好1.首先新建一個springboot...
    布衣小販java閱讀 9,366評論 2 9
  • 昨天是我參加好報寫作后第一次未交作業(yè),多少有點慚愧。其實通過自愿加入寫作并能每天堅持寫,多少還是需要自己的自覺???..
    破曉天晴閱讀 361評論 0 0

友情鏈接更多精彩內容