Cookie 與 Session


  Cookie 與 Session 是很常用的實現 Http 狀態的技術,在不斷的使用中,自己也對其有所理解。我接下來的討論,是基於下面的順序的:

  1、為什么要使用 Cookie 和 Session

由於 Http 協議的請求過程,是基於 TCP/IP 的,當客戶端請求服務器,服務器處理后,進行響應,這個過程是無狀態的。在有些時候,是需要保存一些客戶端的請求信息,識別客戶端的某些狀態,智能的、有針對性的去分析某些客戶端的習慣。這些時候,就需要去記錄客戶端的連接狀態,識別請求的狀態等。為了解決類似的事情,就需要使用到了 Cookie 和 Session。

  2、Cookie 和 Session 的具體知識

(1)Cookie: 在客戶端訪問某個地址時,會將請求交到服務器進行處理,在發送請求的時候,瀏覽器會將頁面的頭部信息一並的交到服務器端進行處理。在處理的過程中,Cookie 在服務器端生成 ,在此同時,可以將一些需要保存的信息,存放到此 Cookie 中。生成 Cookie 對象時,需要確定具體的名稱及具體的值,可以設置當前 Cookie 的過期時間,設置過期時間后,就相當於持久化了 Cookie 中的數據,此時的 Cookie 會以之前的 Cookie 名稱,保存在客戶端。
如果不設置過期時間,則當前 Cookie 的生命期是瀏覽器會話期間,一旦關閉了該瀏覽器,當前的Cookie 就會不存在了,此時的 Cookie 信息是保存在內存中。在服務器端,處理完后,會將生成的 Cookie ,隨着 Http 響應,會在 Http 響應頭中,加上Cookie 信息,瀏覽器接受到響應后,會按照 Http 響應頭里的 Cookie ,在客戶端建立 Cookie 。在下次客戶進行請求的時候,Http 會附帶着已經存儲過的 Cookie ,一並發送到服務器。一個域,在客戶端建立的所以 Cookie 都是可以共享的,只要 Cookie 沒有過期。

(2)Session: Session 是在服務器端生成的,存儲在服務器端,即存在內存中。可以對生成的 Session 設置過期時間,如果不設置過期時間,默認的 Session 過期時間是30 分鍾(在不同的服務器中,它的過期時間略有不同,本文是以 Tomcat 來說的)  但是,Sesssion 的生成的同時,會生成一個與之相關聯的的 SessionID ,此 SessionID的存儲是需要 Cookie 來完成的。 SessionID 是以名稱為 JSESSIONID,其值應該是一個既不會重復,又不容易被找到規律以仿造的字符串。SessionID會隨着此次 Http 響應,一並返回到客戶端,並保存在客戶端中。到當前請求再次發出后,該 SessionID會隨着 Http 頭部,傳到服務器中,服務器依據當前 SessionID 得到與之對應的 Session.

  其中:通過 Cookie 的方式存儲 Session 狀態,只是其中一種方式。如果客戶端禁用了 Cookie 的話,很多網站任然可以存儲用戶的信息。一種處理的方式是URL 重寫,將 SesseionID 直接附加在請求地址的后面。另一種處理的方式是,使用隱藏自動的方式。就是服務器自動的在表單中,添加一個隱藏字段,以便在表單提交時,將 SesseionID 一起傳到服務器,進行識別。

  3、Cookie 和 Session 的具體使用

最近,我在寫一個代碼生成器的時候,我希望在我填寫完數據庫連接信息后,瀏覽器幫我把這些信息保存起來,以免每次我需要使用的時候,都去填寫,浪費時間。下面是我具體的做法:

 1     /**
 2      * 存儲數據庫連接對象
 3      * @author 高青
 4      * 2014-6-14
 5      * @param database 數據庫連接對象
 6      * @param request http 請求對象
 7      * @param response http 響應對象
 8      * @param jonArray 數據庫中的所有表和 JSONArray 對象
 9      * @return null 空
10      */
11     private String storeDatabaseInfo(Database database,
12             HttpServletRequest request, HttpServletResponse response,
13             JSONArray jonArray) {
14         /*
15          * 判斷:
16          * (1)如果 session 存在並且存儲過 database 數據,則不再進行重復保存
17          * (2)如果,沒有,則將數據存儲到 Session 中
18          */
19         
20         HttpSession session = request.getSession(false);
21         if(session != null && session.getAttribute("database") != null){
22             //(1)如果 session 存在並且存儲過 database 數據,則不再進行重復保存
23             
24             log.info("當前回話已經保存過 databse 的數據了,不再進行重復的保存!");
25         }else{
26             //(2)如果,沒有,則將數據存儲到 Session 中
27             
28             session.setAttribute("database", database);
29             session.setMaxInactiveInterval(60*60);
30         }
31         
32         /*
33          * 判斷:
34          * (1)如果 request 中保存過,則不再進行重復保存
35          * (2)如果,沒有,則將數據存儲到 Cookie 中
36          */
37         Cookie[] cookies = request.getCookies();
38         if((cookies != null)){
39             for (Cookie cookie : cookies) {
40                 if (cookie.getName().equals("database")) {
41                     log.info("當前Cookie 中,已經保存過 databse 的數據了,不再進行重復的保存!");
42                     
43                     //(1)如果 request 中保存過,則不再進行重復保存
44                     return jonArray.toString();
45                 }
46             }
47         }
48         
49         //(2)如果,沒有,則將數據存儲到 Cookie 中
50         String databaseInfoStr = database.getDatabaseType() + "_" + database.getUrl() + "_" + 
51                   database.getPort() + "_" +  database.getUser() + "_" + 
52                   database.getPassword() + "_" + database.getDatabaseName() + "_" +  database.getTable();
53         Cookie databaseInfo = new Cookie("database", databaseInfoStr);
54         databaseInfo.setMaxAge(60*60);                  //設置 Cookie 的過期時間 55         databaseInfo.setHttpOnly(true);                  //設置 Cookie 的使用協議 56         databaseInfo.setPath("/CodeGenerator/");            //設置 Cookie 的使用域 57         response.addCookie(databaseInfo);
58         
59         return null;
60     }

 

其中:特別注意的是,在生成 Cookie 后,如果不設置當前 Cookie 的使用,無論有沒有設置 Cookie 的過期時間,當下次訪問的時候,都是獲取不到該名稱對應的 Cookie 的。如果設置databaseInfo.setPath(“/”)使用在全局的環境中,所有的請求都可以使用該 Cookie , 如果設置和項目相關的域,如:databaseInfo.setPath("/CodeGenerator/"),在只會在當前項目的訪問下使用當前 Cookie 。 

  (4)Cookie 和 Session 的區別

首先,Cookie 是存儲在客戶端的,Session 是存儲在服務器端的。

其次,在保存相對安全性低的信息時候,可以考慮使用 Cookie,在相對安全性要求高的信息時候,可以考試使用 Session。畢竟 Cookie 存在客戶端,其他人可以查找並分析的。

最后,在對性能要求高的時候,不適合使用 Session 的,因為 Session 會一直存在服務器的,直到當前 Session 過期,而且 Cookie 存儲是字符串類型的信息,而 Session 可以存儲任何形式的信息,Session 也不存在訪問域的限制。

個人覺得,在存儲相對持久的信息時,應考慮使用 Cookie ,因為 Cookie 可以以文件的形式,存儲在客戶端。在進行一些登錄的驗證及信息攔截的時候,可以使用 Session。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM