Cookie探究

什麼是Cookie?

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

cookie機制

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

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

 

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

我在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);
    }

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

 

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

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時,時間已經過期

 

當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到底有什麼區別呢?

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

 

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

 

修改或者刪除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是否過期,而不能用服務端來判斷。

 

我們無法在服務端通過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

 

發佈了123 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章