首頁  >  文章  >  Java  >  cookie、session的對比

cookie、session的對比

巴扎黑
巴扎黑原創
2017-07-21 16:58:401213瀏覽
一、cookie機制與session機制的差別

  具體來說cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在伺服器端保持狀態的方案。
  同時我們也看到,由於在伺服器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要藉助於cookie機制來達到保存標識的目的,但實際上還有其他選擇。
二、會話cookie和持久cookie的區別
  如果不設定過期時間,則表示這個cookie生命週期為瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。這種生命期為瀏覽會話期的cookie被稱為會話cookie。會話cookie一般不保存在硬碟上而是保存在記憶體裡。
  如果設定了過期時間,瀏覽器就會把cookie儲存到硬碟上,關閉後再次開啟瀏覽器,這些cookie依然有效直到超過設定的過期時間。
  儲存在硬碟上的cookie可以在不同的瀏覽器進程間共享,例如兩個IE視窗。而對於儲存在記憶體的cookie,不同的瀏覽器有不同的處理方式。
三、如何利用實作自動登入
  當使用者在某個網站註冊後,就會收到一個惟一用戶ID的cookie。客戶後來重新連接時,這個用戶ID會自動返回,伺服器對它進行檢查,確定它是否為註冊用戶且選擇了自動登錄,從而使用戶無需給出明確的用戶名和密碼,就可以訪問伺服器上的資源。
四、如何依照使用者的嗜好自訂網站
  網站可以使用cookie記錄使用者的意願。對於簡單的設置,網站可以直接將頁面的設定儲存在cookie中完成自訂。然而對於更複雜的定制,網站只需僅將一個惟一的標識符發送給用戶,由伺服器端的資料庫儲存每個標識符對應的頁面設定。
五、cookie的發送
1.建立Cookie物件
2.設定最大時效
3.將Cookie放入到HTTP回應標頭
  如果你建立了一個cookie,並將他傳送到瀏覽器,預設情況下它是一個會話層級的cookie:儲存在瀏覽器的記憶體中,使用者退出瀏覽器之後被刪除。如果你希望瀏覽器將該cookie儲存在磁碟上,則需要使用maxAge,並給出一個以秒為單位的時間。將最大時效設為0則是指令瀏覽器刪除該 cookie。
  傳送cookie需要使用HttpServletResponse的addCookie方法,將cookie插入到一個 Set-Cookie HTTP請求標頭中。由於這個方法並沒有修改任何先前指定的Set-Cookie標頭,而是建立新的標頭,因此我們將這個方法稱為是addCookie,而非setCookie。同樣要記住回應報頭必須在任何文件內容傳送到客戶端之前設定。
六、cookie的讀取
1.呼叫request.getCookie
  要取得有瀏覽器發送來的cookie,需要呼叫HttpServletRequest的getCookies方法,這個呼叫傳回Cookie物件的數組,對應由HTTP請求中Cookie報頭輸入的值。
2.對陣列進行循環,呼叫每個cookie的getName方法,直到找到感興趣的cookie為止
  cookie與你的主機(域)相關,而非你的servlet或JSP頁面。因而,儘管你的servlet可能只發送了單一cookie,你可能會得到許多不相關的cookie。
例如:
  String cookieName = “userID”;
Cookie cookies[] = request.getCookies();
if (cookies!=null){
for(int i=0; i
 Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName())){
doSomethingWith(cookie.getValue());
}
}
}
七、如何使用cookie偵測初訪者
A.呼叫HttpServletRequest.getCookies()取得Cookie陣列
B.在迴圈中擷取指定名字的cookie是否存在以及對應的值是否正確
C.如果是則退出循環並設定區別標識
D.根據區別標識判斷用戶是否為初訪者從而進行不同的操作
八、使用cookie檢測初訪者的常見錯誤
  不能僅僅因為cookie數組中不存在在特定的資料項目就認為用戶是個初訪者。
  但是,如果數組非null,也不過是顯示客戶曾經到過你的網站或域,並不能說明他們曾經訪問過你的servlet。依據路徑的設置,其中的任何cookie都有可能傳回給使用者的瀏覽器。
  正確的做法是判斷cookie數組是否為空且是否存在指定的Cookie物件且值正確。屬性的注意問題
  屬性是從伺服器傳送到瀏覽器的標頭的一部分;但它們不屬於由瀏覽器傳回給伺服器的報頭。伺服器輸出到客戶端的cookie;伺服器端來自於瀏覽器的cookie並沒有設定這些屬性。  因而不要期望透過request.getCookies得到的cookie中可以使用這個屬性。這意味著,你不能僅僅通過設定cookie的最大時效,發出它,在隨後的輸入數組中查找適當的cookie,讀取它的值,修改它並將它存回Cookie,從而實現不斷改變的cookie值。
十、如何使用cookie記錄各個用戶的訪問計數
1.獲取cookie數組中專門用於統計用戶訪問次數的cookie的值
2.將值轉換成int型
3.將值加1並用原來的名稱重新建立一個Cookie物件
4.重新設定最大時效
5.將新的cookie輸出
十一、session在不同環境下的不同意義
  session ,中文經常翻譯為會話,其本來的含義是指有始有終的一系列動作/訊息,例如打電話是從拿起電話撥號到掛斷電話這中間的一系列過程可以稱之為一個session。
  然而當session一詞與網路協定相關聯時,它又往往隱含了「面向連線」和/或「保持狀態」這樣兩個意義。
  session在Web開發環境下的語意又有了新的擴展,它的意義是指一類用來在客戶端與伺服器端之間保持狀態的解決方案。有時候Session也用來指稱這種解決方案的儲存結構。
十二、session的機制
  session機制是一種伺服器端的機制,伺服器使用一種類似散列表的結構(也可能就是使用散列表)來保存資訊。
  但程式需要為某個客戶端的請求建立一個session的時候,伺服器首先檢查這個客戶端的請求裡是否包含了一個session標識-稱為session id,如果已經包含一個session id則說明以前已經為此客戶創建過session,伺服器就按照session id把這個session檢索出來使用(如果檢索不到,可能會新建一個,這種情況可能出現在服務端已經刪除了該用戶對應的session對象,但用戶人為地在請求的URL後面附加上一個JSESSION的參數)。
  如果客戶要求不包含session id,則為此客戶建立一個session並且產生一個與此session相關聯的session id,這個session id將在本次回應中傳回給客戶端儲存。
十三、保存session id的幾種方式
A.保存session id的方式可以採用cookie,這樣在互動過程中瀏覽器可以自動的按照規則把這個標識傳送給伺服器。
B.由於cookie可以被人為的禁止,必須有其它的機制以便在cookie被禁止時仍然能夠把session id傳回伺服器,經常採用的一種技術叫做URL重寫,就是把session id附加在URL路徑的後面,附加的方式也有兩種,一種是作為URL路徑的附加信息,另一種是作為查詢字串附加在URL後面。網路在整個互動過程中始終保持狀態,就必須在每個客戶端可能請求的路徑後面都包含這個session id。
C.另一種技術叫做表單隱藏欄位。就是伺服器會自動修改表單,新增一個隱藏字段,以便在表單提交時能夠把session id傳回伺服器。
十四、session什麼時候被創建
  一個常見的錯誤是以為session在有客戶端存取時就被創建,然而事實是直到某server端程式(如Servlet)呼叫HttpServletRequest.getSession(true)這樣的語句時才會被創造出來。
十五、session何時被刪除
session在下列情況下被刪除:
A.程式呼叫HttpSession.invalidate()
B.距離上一次收到客戶端發送的session id時間間隔超過了session的最大有效時間
C.伺服器程序被停止
  再次注意關閉瀏覽器只會使儲存在客戶端瀏覽器記憶體中的session cookie失效,不會使伺服器端的session物件失效。
十六、URL重寫有什麼缺點
  對所有的URL使用URL重寫,包括超鏈接,form的action,和重定向的URL。每個引用你的網站的URL,以及那些回傳給使用者的URL(即使透過間接手段,例如伺服器重定向中的Location欄位)都要添加額外的資訊。
  這表示在你的網站上不能有任何靜態的HTML頁面(至少靜態頁面中不能有任何連結到網站動態頁面的連結)。因此,每個頁面都必須使用servlet或 JSP動態產生。即使所有的頁面都動態生成,如果用戶離開了會話並通過書籤或鏈接再次回來,會話的信息都會丟失,因為存儲下來的鏈接含有錯誤的標識信息——該URL後面的SESSION ID已經過期了。  
十七、使用隱藏的表單網域有什麼缺點
只有當每個頁面都是有表單提交而動態產生時,才能使用這種方法。點擊常規的超文本連結並不產生表單提交,因此隱藏的表單網域不能支援通常的會話跟踪,只能用於一系列特定的操作中,例如線上商店的結帳流程
十八、會話跟踪的基本步驟
1.存取與目前請求相關的會話物件
2.尋找與會話相關的資訊
3.儲存會話資訊
4.廢棄會話資料
十九、getSession()/getSession(true)、getSession(false)的區別
getSession()/getSession(true):當session存在時傳回該session,否則新建一個session並傳回該物件
getSession(false):當session存在時傳回該session,否則不會新建session,回傳null
二十、如何將資訊與會話關聯起來
  setAttribute會取代任何先前設定的值;如果想要在不提供任何代替的情況下移除某個值,則應使用removeAttribute。這個方法會觸發所有實作了HttpSessionBindingListener介面的值的valueUnbound方法。
二十一、會話屬性的型別有什麼限制嗎
  通常會話屬性的型別只要是Object就可以了。除了null或基本類型,如int,double,boolean。
  如果要使用基本類型的值作為屬性,必須將其轉換為對應的封裝類別物件
二十二、如何廢棄會話資料
A.只移除自己寫的servlet所建立的資料:
呼叫removeAttribute(“key”)將指定鍵關聯的值廢棄
B.刪除整個會話(在目前Web應用中):
呼叫invalidate,將整個會話廢棄掉。這樣做會遺失該使用者的所有會話數據,而非僅由我們servlet或JSP頁面所建立的會話資料
C.將使用者從系統中登出並刪除所有屬於他(或她)的會話
呼叫logOut,將客戶從Web伺服器中註銷,同時廢棄所有與該使用者相關聯的會話(每個Web應用至多一個)。這個操作有可能影響到伺服器上多個不同的Web應用。
二十三、使用isNew來判斷使用者是否為新舊使用者的錯誤做法
  public boolean isNew()方法如果會話尚未和客戶程式(瀏覽器)發生任何联系,則這個方法傳回true,這一般是因為會話是新建的,不是由輸入的客戶請求所引起的。
  但如果isNew回傳false,只不過是說明他之前曾經訪問過該Web應用,並不代表他們曾訪問過我們的servlet或JSP頁面。
  因為session是與使用者相關的,在使用者之前造訪的每一個頁面都有可能創建了會話。因此isNew為false只能說使用者之前訪問過該Web應用,session可以是當前頁面創建,也可能是由用戶之前訪問過的頁面創建的。
  正確的做法是判斷某個session中是否存在某個特定的key且其value是否正確
二十四、Cookie的過期和Session的超時有什麼區別
  會話的超時由伺服器來維護,它不同於Cookie的失效日期。首先,會話一般基於駐留記憶體的cookie不是持續性的cookie,因而也就沒有截至日期。即使截取到JSESSIONID cookie,並為它設定一個失效日期發送出去。瀏覽器會話和伺服器會話也會截然不同。
二十五、session cookie和session物件的生命週期是一樣的嗎
  當使用者關閉了瀏覽器雖然session cookie已經消失,但session物件仍然保存在伺服器端
二十六、是否只要關閉瀏覽器,session就消失了
  程式一般都是在用戶做log off的時候發個指令去刪除session,然而瀏覽器從來不會主動在關閉之前通知伺服器它將要被關閉,因此伺服器根本不會有機會知道瀏覽器已經關閉。伺服器會一直保留這個會話物件直到它處於非活動狀態超過設定的間隔為止。
  之所以會有這種錯誤的認識,是因為大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個session id就消失了,再次連接到伺服器時也就無法找到原來的session。
  如果伺服器設定的cookie被儲存到硬碟上,或者使用某種手段改寫瀏覽器發出的HTTP請求標頭,把原來的session id送到伺服器,則再次開啟瀏覽器仍然能夠找到原來的session。
  恰恰是由於關閉瀏覽器不會導致session被刪除,迫使伺服器為session設定了一個失效時間,當距離客戶上一次使用session的時間超過了這個失效時間時,伺服器就可以認為客戶端已經停止了活動,才會刪除session以節省儲存空間。
  由此我們可以得出如下結論:
  關閉瀏覽器,只會是瀏覽器端內存裡的session cookie消失,但不會使保存在伺服器端的session物件消失,同樣也不會使已經儲存到硬碟上的持久化cookie消失。
二十七、開啟兩個瀏覽器視窗存取應用程式會使用同一個session還是不同的session
  通常session cookie是不能跨視窗使用的,當你新開了一個瀏覽器視窗進入相同頁面時,系統會賦予你一個新的session id,這樣我們資訊共享的目的就達不到了。
此時我們可以先把session id保存在persistent cookie中(透過設定session的最大有效時間),然後在新視窗中讀出來,就可以得到上一個視窗的session id了,這樣透過session cookie和persistent cookie的結合我們就可以實現了跨視窗的會話追蹤。
二十八、如何使用會話顯示每個客戶的訪問次數
  由於客戶的訪問次數是一個整型的變量,但session的屬性類型中不能使用int,double,boolean等基本類型的變量,所以我們要用到這些基本類型的封裝類型物件作為session物件中屬性的值
  但像Integer是一種不可修改(Immutable)的資料結構:建置後就不能更改。這意味著每個請求都必須建立新的Integer對象,之後使用setAttribute來取代之前存在的舊的屬性的值。例如:
HttpSession session = request.getSession();
SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(“SomeIdentifier”);
if (value= =#null){#cmm){#OomIvaluea. (…); // 新建一個不可更改物件
}else{
value = new SomeImmutableClass(calculatedFrom(value)); // 對value重新計算後建立新的物件
}
session.setAttribute(“someIdentifier”,value); // 使用新建立的物件覆蓋原來的老的物件
二十九、如何使用會話累計使用者的資料
  使用可變的資料結構,例如數組、List、Map或含有可寫入欄位的應用程式專有的資料結構。透過這種方式,除非首次分配對象,否則不需要呼叫setAttribute。例如
HttpSession session = request.getSession();
SomeMutableClass value = (SomeMutableClass)session.getAttribute(“someIdentifier”);
if(value = = null){
value = new SomeMutableClass( …);
session.setAttribute(“someIdentifier”,value);
}else{
value.updateInternalAttribute(…); // 如果已經存在該物件則更新其屬性而不需重新設定屬性
}
三十、不可更改物件和可更改物件在會話資料更新時的不同處理
  不可更改物件因為一旦創建之後就不能更改,所以每次要修改會話中屬性的值的時候,都需要呼叫setAttribute(“someIdentifier”,newValue)來代替原有的屬性的值,否則屬性的值不會被更新可更改物件因為其自身一般提供了修改自身屬性的方法,所以每次要修改會話中屬性的值的時候,只要呼叫該可更改物件的相關修改自身屬性的方法就可以了。這意味著我們就不需要呼叫 setAttribute方法了。

以上是cookie、session的對比的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn