故事背景
同 http, html, REST API 同樣屬於基礎性的知識內容。javascript
[Node.js] 07 - Html and Httpphp
[Node.js] 08 - Web Server and REST APIhtml
理解Cookie和Session機制【知識體系比較全】java
Cookie
1、服務器端設置Cookie
<?php
setcookie("user", "runoob", time()+3600);
?>
--------------------------------------------
<?php $expire=time()+60*60*24*30; setcookie("user", "runoob", $expire); ?>
<html> // 要在此以前 .....
在發送 cookie 時,cookie 的值會自動進行 URL 編碼,,在取回時進行自動解碼。web
<?php
// 設置 cookie 過時時間爲過去 1 小時
setcookie("user", "", time()-3600);
?>
2、是否已設置了 cookie
<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
</head>
<body>
<?php
if (isset($_COOKIE["user"])) # 這個變量存在否?
echo "歡迎 " . $_COOKIE["user"] . "!<br>";
else
echo "普通訪客!<br>";
?>
</body>
</html>
3、瀏覽器不支持cookie
Ref: 瀏覽器不支持cookie的解決辦法【圖文】算法
瀏覽器不支持cookie的緣由之一就是瀏覽器設置的問題。用戶的瀏覽器設置了比較高的保護級別,當使用的網頁不是比較有名的名站的話,就會被瀏覽器誤認爲是釣魚網站或者是攜帶了木馬的網站。sql
另外一個致使不支持瀏覽器cookie的緣由就是瀏覽器文件損壞或者是系統文件損壞。數據庫
除了上述兩種故障緣由以外,發生瀏覽器不支持cookie的緣由還多是因爲某一個網站自己的問題。例如,一些網站服務器或者網頁自己腳本的問題。vim
Session
在因特網上問題出現了:因爲 HTTP 地址沒法保持狀態,Web 服務器並不知道您是誰以及您作了什麼。跨域
Session 的工做機制是:爲每一個訪客建立一個惟一的 id (UID),並基於這個 UID 來存儲變量。UID 存儲在 cookie 中,或者經過 URL 進行傳導。
1、存儲 Session 變量
<?php
session_start();
// 存儲 session 數據
$_SESSION['views']=1;
?>
-------------------------------------
<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
</head>
<body>
<?php
// 檢索 session 數據
echo "瀏覽量:". $_SESSION['views'];
?>
</body>
</html>
<?php
session_start();
if(isset($_SESSION['views']))
{
unset($_SESSION['views']); # 釋放指定的 session 變量
}
?>
-----------------------------------
<?php
session_destroy(); # 重置 session,將失去全部已存儲的 session 數據 ?>
2、簡單的 page-view 計數器
<?php
session_start();
if(isset($_SESSION['views']))
{
$_SESSION['views']=$_SESSION['views']+1;
}
else
{
$_SESSION['views']=1;
}
echo "瀏覽量:". $_SESSION['views'];
?>
經常使用的會話跟蹤技術是Cookie與Session。
-
- Cookie經過在客戶端記錄信息肯定用戶身份,
- Session經過在服務器端記錄信息肯定用戶身份。
問題:
比較說明何時不能用Cookie,何時不能用Session。
2、Cookie 基本認識
Cookie就是由服務器發給客戶端的特殊信息,以文本文件的方式存放在客戶端。
而後客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息。
[1] 請求響應
當用戶使用瀏覽器訪問一個支持Cookie的網站的時候,用戶會提供包括用戶名在內的我的信息而且提交至服務器;
接着,服務器在向客戶端回傳相應的超文本的同時也會發回這些我的信息,存放於HTTP響應頭(Response Header);
[2] 收到服務器的首次響應
當客戶端瀏覽器接收到來自服務器的響應以後,瀏覽器會將這些信息存放在一個統一的位置:
對於Windows操做系統而言,咱們能夠從: [系統盤]:\Documents and Settings\[用戶名]\Cookies目錄中找到存儲的Cookie;
[3] 再次訪問
自此,客戶端再向服務器發送請求的時候,都會把相應的Cookie再次發回至服務器。
而此次,Cookie信息則存放在HTTP請求頭(Request Header)了。
[4] 達到的效果
有了Cookie這樣的技術實現,服務器在接收到來自客戶端瀏覽器的請求以後,就可以經過分析存放於請求頭的Cookie獲得客戶端特有的信息,從而動態生成與該客戶端相對應的內容。
一般,咱們能夠從不少網站的登陸界面中看到「請記住我」這樣的選項,若是你勾選了它以後再登陸,那麼在下一次訪問該網站的時候就不須要進行重複而繁瑣的登陸動做了,而這個功能就是經過Cookie實現的。
在程序中,會話跟蹤是很重要的事情。理論上,一個用戶的全部請求操做都應該屬於同一個會話,而另外一個用戶的全部請求操做則應該屬於另外一個會話,兩者不能混淆。
例如,用戶A在超市購買的任何商品都應該放在A的購物車內,不管是用戶A什麼時間購買的,這都是屬於同一個會話的,不能放入用戶B或用戶C的購物車內,這不屬於同一個會話。
而Web應用程序是使用HTTP協議傳輸數據的。HTTP協議是無狀態的協議。一旦數據交換完畢,客戶端與服務器端的鏈接就會關閉,再次交換數據須要創建新的鏈接。這就意味着服務器沒法從鏈接上跟蹤會話。即用戶A購買了一件商品放入購物車內,當再次購買商品時服務器已經沒法判斷該購買行爲是屬於用戶A的會話仍是用戶B的會話了。要跟蹤該會話,必須引入一種機制。
Cookie就是這樣的一種機制。它能夠彌補HTTP協議無狀態的不足。在Session出現以前,基本上全部的網站都採用Cookie來跟蹤會話。
若是你把Cookies當作爲http協議的一個擴展的話,理解起來就容易的多了,其實本質上cookies就是http的一個擴展。有兩個http頭部是專門負責設置以及發送cookie的,它們分別是Set-Cookie以及Cookie。
當服務器返回給客戶端一個http響應信息時,其中若是包含Set-Cookie這個頭部時,意思就是指示客戶端創建一個cookie,而且在後續的http請求中自動發送這個cookie到服務器端,直到這個cookie過時。
若是cookie的生存時間是整個會話期間的話,那麼瀏覽器會將cookie保存在內存中,瀏覽器關閉時就會自動清除這個cookie。
另一種狀況就是保存在客戶端的硬盤中,瀏覽器關閉的話,該cookie也不會被清除,下次打開瀏覽器訪問對應網站時,這個cookie就會自動再次發送到服務器端。
一個cookie的設置以及發送過程分爲如下四步:

這兩種傳遞數據的方式,比起用cookies來傳遞數據更穩定,由於cookie可能被禁用,可是以GET以及POST方式傳遞數據時,不存在這種狀況。
GET /index.php?foo=bar HTTP/1.1 Host: example.org
----------------------------------------------------------------------------------------------------------------------
POST /index.php HTTP/1.1 Host: example.org Content-Type: application/x-www-form-urlencoded Content-Length: 7
foo=bar
----------------------------------------------------------------------------------------------------------------------
POST /index.php?myget=foo HTTP/1.1 Host: example.orgContent-Type: application/x-www-form-urlencoded Content-Length: 11
mypost=bar
Cookie對象使用key-value屬性對的形式保存用戶狀態,一個Cookie對象保存一個屬性對,一個request或者response同時使用多個Cookie。
根據Cookie規範,瀏覽器訪問Google只會攜帶Google的Cookie,而不會攜帶Baidu的Cookie。Google也只能操做Google的Cookie,而不能操做Baidu的Cookie。
3、Cookie 深刻認識
中文與英文字符不一樣,中文屬於Unicode字符,在內存中佔4個字符,而英文屬於ASCII字符,內存中只佔2個字節。Cookie中使用Unicode字符時須要對Unicode字符進行編碼,不然會亂碼。
提示:Cookie中保存中文只能編碼。通常使用UTF-8編碼便可。不推薦使用GBK等中文編碼,由於瀏覽器不必定支持,並且JavaScript也不支持GBK編碼。
Cookie不只可使用ASCII字符與Unicode字符,還可使用二進制數據。例如在Cookie中使用數字證書,提供安全度。使用二進制數據時也須要進行編碼。
注意:本程序僅用於展現Cookie中能夠存儲二進制內容,並不實用。因爲瀏覽器每次請求服務器都會攜帶Cookie,所以Cookie內容不宜過多,不然影響速度。Cookie的內容應該少而精。
除了name與value以外,Cookie還具備其餘幾個經常使用的屬性。每一個屬性對應一個getter方法與一個setter方法。Cookie類的全部屬性以下所示。
String name:該Cookie的名稱。Cookie一旦建立,名稱便不可更改。
Object value:該Cookie的值。若是值爲Unicode字符,須要爲字符編碼。若是值爲二進制數據,則須要使用BASE64編碼。
int maxAge:該Cookie失效的時間,單位秒。
若是爲正數,則該Cookie在>maxAge秒以後失效。
若是爲負數,該Cookie爲臨時Cookie,關閉瀏覽器即失效,瀏覽器也不會以任何形式保存該Cookie。
若是爲零,表示刪除該Cookie。默認爲–1。
boolean secure:該Cookie是否僅被使用安全協議傳輸。安全協議。安全協議有HTTPS,SSL等,在網絡上傳輸數據以前先將數據加密。默認爲false。
String path:該Cookie的使用路徑。若是設置爲「/sessionWeb/」,則只有contextPath爲「/sessionWeb」的程序能夠訪問該Cookie。若是設置爲「/」,則本域名下contextPath均可以訪問該Cookie。注意最後一個字符必須爲「/」。
String domain:能夠訪問該Cookie的域名。若是設置爲「.google.com」,則全部以「google.com」結尾的域名均可以訪問該Cookie。注意第一個字符必須爲「.」。
String comment:該Cookie的用處說明。瀏覽器顯示Cookie信息的時候顯示該說明。
int version:該Cookie使>用的版本號。
0 - 表示遵循Netscape的Cookie規範,
1 - 表示遵循W3C的RFC 2109規範。
Cookie的maxAge決定着Cookie的有效期,單位爲秒(Second)。Cookie中經過getMaxAge()方法與setMaxAge(int maxAge)方法來讀寫maxAge屬性。
[1] 若是maxAge屬性爲正數,則表示該Cookie會在maxAge秒以後自動失效。瀏覽器會將maxAge爲正數的Cookie持久化,即寫到對應的Cookie文件中。不管客戶關閉了瀏覽器仍是電腦,只要還在maxAge秒以前,登陸網站時該Cookie仍然有效。下面代碼中的Cookie信息將永遠有效。
Cookie cookie = new Cookie("username", "helloweenvsfei"); // 新建Cookie
cookie.setMaxAge(Integer.MAX_VALUE); // 設置生命週期爲MAX_VALUE
response.addCookie(cookie); // 輸出到客戶端
[2] 若是maxAge爲負數,則表示該Cookie僅在本瀏覽器窗口以及本窗口打開的子窗口內有效,關閉窗口後該Cookie即失效。maxAge爲負數的Cookie,爲臨時性Cookie,不會被持久化,不會被寫到Cookie文件中。Cookie信息保存在瀏覽器內存中,所以關閉瀏覽器該Cookie就消失了。Cookie默認的maxAge值爲–1。
[3] 若是maxAge爲0,則表示刪除該Cookie。Cookie機制沒有提供刪除Cookie的方法,所以經過設置該Cookie即時失效實現刪除Cookie的效果。失效的Cookie會被瀏覽器從Cookie文件或者內存中刪除:
Cookie cookie = new Cookie("username", "helloweenvsfei"); // 新建Cookie
cookie.setMaxAge(0); // 設置生命週期爲0,不能爲負數
response.addCookie(cookie); // 必須執行這一句
response對象提供的Cookie操做方法只有一個添加操做add(Cookie cookie)。要想修改Cookie只能使用一個同名的Cookie來覆蓋原來的Cookie,達到修改的目的。刪除時只須要把maxAge修改成0便可。
注意:從客戶端讀取Cookie時,包括maxAge在內的其餘屬性都是不可讀的,也不會被提交。
-
- 瀏覽器提交Cookie時只會提交name與value屬性。
- maxAge屬性只被瀏覽器用來判斷Cookie是否過時。
$ vim .mozilla/firefox/6lpoihdv.default/cookies.sqlite

Cookie並不提供修改、刪除操做。若是要修改某個Cookie,只須要新建一個同名的Cookie,添加到response中覆蓋原來的Cookie。若是要刪除某個Cookie,只須要新建一個同名的Cookie,並將maxAge設置爲0,並添加到response中覆蓋原來的Cookie。注意是0而不是負數。負數表明其餘的意義。讀者能夠經過上例的程序進行驗證,設置不一樣的屬性。
注意:修改、刪除Cookie時,新建的Cookie除value、maxAge以外的全部屬性,例如name、path、domain等,都要與原Cookie徹底同樣。不然,瀏覽器將視爲兩個不一樣的Cookie不予覆蓋,致使修改、刪除失敗。
Cookie 是不可跨域名的。域名www.google.com頒發的Cookie不會被提交到域名www.baidu.com去。這是由Cookie的隱私安全機制決定的。隱私安全機制可以禁止網站非法獲取其餘網站的Cookie。
正常狀況下,同一個一級域名下的兩個二級域名如www.helloweenvsfei.com和images.helloweenvsfei.com也不能交互使用Cookie,由於兩者的域名並不嚴格相同。若是想全部helloweenvsfei.com名下的二級域名均可以使用該Cookie,須要設置Cookie的domain參數,例如:
Cookie cookie = new Cookie("time","20080808"); // 新建Cookie
cookie.setDomain(".helloweenvsfei.com"); // 設置域名
cookie.setPath("/"); // 設置路徑
cookie.setMaxAge(Integer.MAX_VALUE); // 設置有效期
response.addCookie(cookie); // 輸出到客戶端
讀者能夠修改本機C:\WINDOWS\system32\drivers\etc下的hosts文件來配置多個臨時域名,
而後使用setCookie.jsp程序來設置跨域名Cookie驗證domain屬性。
注意:domain參數必須以點(".")開始。另外,name相同但domain不一樣的兩個Cookie是兩個不一樣的Cookie。若是想要兩個域名徹底不一樣的網站共有Cookie,能夠生成兩個Cookie,domain屬性分別爲兩個域名,輸出到客戶端。
domain屬性決定運行訪問Cookie的域名,而path屬性決定容許訪問Cookie的路徑(ContextPath)。例如,若是隻容許/sessionWeb/下的程序使用Cookie,能夠這麼寫:
Cookie cookie = new Cookie("time","20080808"); // 新建Cookie
cookie.setPath("/session/"); // 設置路徑
response.addCookie(cookie); // 輸出到客戶端
設置爲「/」時容許全部路徑使用Cookie。path屬性須要使用符號「/」結尾。name相同但domain不一樣的兩個Cookie也是兩個不一樣的Cookie。
注意:頁面只能獲取它屬於的Path的Cookie。例如/session/test/a.jsp不能獲取到路徑爲/session/abc/的Cookie。使用時必定要注意。
-
-
domain表示的是cookie所在的域,默認爲請求的地址,如網址爲www.test.com/test/test.aspx,那麼domain默認爲www.test.com。而跨域訪問,如域A爲t1.test.com,域B爲t2.test.com,那麼在域A生產一個令域A和域B都能訪問的cookie就要將該cookie的domain設置爲.test.com;若是要在域A生產一個令域A不能訪問而域B能訪問的cookie就要將該cookie的domain設置爲t2.test.com。
-
path表示cookie所在的目錄,默認爲/,就是根目錄。在同一個服務器上有目錄以下:/test/,/test/cd/,/test/dd/,現設一個cookie1的path爲/test/,cookie2的path爲/test/cd/,那麼test下的全部頁面均可以訪問到cookie1,而/test/和/test/dd/的子頁面不能訪問cookie2。這是由於cookie能讓其path路徑下的頁面訪問。
-
瀏覽器會將domain和path都相同的cookie保存在一個文件裏,cookie間用*隔開。
HTTP協議不只是無狀態的,並且是不安全的。使用HTTP協議的數據不通過任何加密就直接在網絡上傳播,有被截獲的可能。使用HTTP協議傳輸很機密的內容是一種隱患。
若是不但願Cookie在HTTP等非安全協議中傳輸,能夠設置Cookie的secure屬性爲true。瀏覽器只會在HTTPS和SSL等安全協議中傳輸此類Cookie。下面的代碼設置secure屬性爲true:
Cookie cookie = new Cookie("time", "20080808"); // 新建Cookie
cookie.setSecure(true); // 設置安全屬性
response.addCookie(cookie); // 輸出到客戶端
提示:secure屬性並不能對Cookie內容加密,於是不能保證絕對的安全性。若是須要高安全性,須要在程序中對Cookie內容加密、解密,以防泄密。
Cookie是保存在瀏覽器端的,所以瀏覽器具備操做Cookie的先決條件。瀏覽器可使用腳本程序如JavaScript或者VBScript等操做Cookie。這裏以JavaScript爲例介紹經常使用的Cookie操做。例以下面的代碼會輸出本頁面全部的Cookie。
<script>document.write(document.cookie);</script>
因爲JavaScript可以任意地讀寫Cookie,有些好事者便想使用JavaScript程序去窺探用戶在其餘網站的Cookie。不過這是徒勞的,W3C組織早就意識到JavaScript對Cookie的讀寫所帶來的安全隱患並加以防備了,W3C標準的瀏覽器會阻止JavaScript讀寫任何不屬於本身網站的Cookie。換句話說,A網站的JavaScript程序讀寫B網站的Cookie不會有任何結果。
通常不把密碼等重要信息保存到Cookie中。
採用另外一種方案,只在登陸時查詢一次數據庫,之後訪問驗證登陸信息時再也不查詢數據庫。
-
- 把帳號按照必定的規則加密後,連同帳號一塊保存到Cookie中。
- 下次訪問時只須要判斷帳號的加密規則是否正確便可。
本例把帳號保存到名爲 account 的Cookie中,把帳號連同密鑰用MD1算法加密後保存到名爲ssid的Cookie中。驗證時驗證Cookie中的帳號與密鑰加密後是否與Cookie中的ssid相等。
提示:該加密機制中最重要的部分爲算法與密鑰。因爲MD1算法的不可逆性,即便用戶知道了帳號與加密後的字符串,也不可能解密獲得密鑰。所以,只要保管好密鑰與算法,該機制就是安全的。
4、Session機制
除了使用Cookie,Web應用程序中還常用Session來記錄客戶端狀態。
Session是服務器端使用的一種記錄客戶端狀態的機制,使用上比Cookie簡單一些,相應的也增長了服務器的存儲壓力。
Session技術則是服務端的解決方案,它是經過服務器來保持狀態的。
因爲Session這個詞彙包含的語義不少,所以須要在這裏明確一下 Session的含義。
* 首先,咱們一般都會把Session翻譯成會話,所以咱們能夠把客戶端瀏覽器與服務器之間一系列交互的動做稱爲一個 Session。
從這個語義出發,咱們會提到Session持續的時間,會提到在Session過程當中進行了什麼操做等等;
* 其次,Session指的是服務器端爲客戶端所開闢的存儲空間,在其中保存的信息就是用於保持狀態。
從這個語義出發,咱們則會提到往Session中存放什麼內容,如何根據鍵值從 Session中獲取匹配的內容等。
-
- 要使用Session,第一步固然是建立Session了。那麼Session在什麼時候建立呢?固然仍是在服務器端程序運行的過程當中建立的,不一樣語言實現的應用程序有不一樣建立Session的方法,而在Java中是經過調用HttpServletRequest的getSession方法(使用true做爲參數)建立的。
- 在建立了Session的同時,服務器會爲該Session生成惟一的Session id,而這個Session id在隨後的請求中會被用來從新得到已經建立的Session;
- 在Session被建立以後,就能夠調用Session相關的方法往Session中增長內容了,而這些內容只會保存在服務器中,發到客戶端的只有Session id;
- 當客戶端再次發送請求的時候,會將這個Session id帶上,服務器接受到請求以後就會依據Session id找到相應的Session,從而再次使用之。正式這樣一個過程,用戶的狀態也就得以保持了。
若是說Cookie機制是經過檢查客戶身上的「通行證」來肯定客戶身份的話,那麼Session機制就是經過檢查服務器上的「客戶明細表」來確認客戶身份。
Session至關於程序在服務器上創建的一份客戶檔案,客戶來訪的時候只須要查詢客戶檔案表就能夠了。【狀態保存】
登陸界面驗證用戶登陸信息,若是登陸正確,就把用戶信息以及登陸時間保存進Session,而後轉到歡迎頁面welcome.jsp。
注意:程序中Session中直接保存了Person類對象與Date類對象,使用起來要比Cookie方便。當多個客戶端執行程序時,服務器會保存多個客戶端的Session。獲取Session的時候也不須要聲明獲取誰的Session。Session機制決定了當前客戶只會獲取到本身的Session,而不會獲取到別人的Session。各客戶的Session也彼此獨立,互不可見。
提示:Session的使用比Cookie方便,可是過多的Session存儲在服務器內存中,會對服務器形成壓力。
Session保存在服務器端。爲了得到更高的存取速度,服務器通常把Session放在內存裏。每一個用戶都會有一個獨立的Session。若是Session內容過於複雜,當大量客戶訪問服務器時可能會致使內存溢出。所以,Session裏的信息應該儘可能精簡。
Session在用戶第一次訪問服務器的時候自動建立。須要注意只有訪問JSP、Servlet等程序時纔會建立Session,只訪問HTML、IMAGE等靜態資源並不會建立Session。若是還沒有生成Session,也可使用request.getSession(true)強制生成Session。
Session生成後,只要用戶繼續訪問,服務器就會更新Session的最後訪問時間,並維護該Session。用戶每訪問服務器一次,不管是否讀寫Session,服務器都認爲該用戶的Session「活躍(active)」了一次。
因爲會有愈來愈多的用戶訪問服務器,所以Session也會愈來愈多。爲防止內存溢出,服務器會把長時間內沒有活躍的Session從內存刪除。這個時間就是Session的超時時間。若是超過了超時時間沒訪問過服務器,Session就自動失效了。
Session的超時時間爲maxInactiveInterval屬性,能夠經過對應的getMaxInactiveInterval()獲取,經過setMaxInactiveInterval(longinterval)修改。
Session的超時時間也能夠在web.xml中修改。另外,經過調用Session的invalidate()方法可使Session失效。
void setAttribute(String attribute, Object value): 設置Session屬性。value參數能夠爲任何Java Object。一般爲Java Bean。value信息不宜過大
String getAttribute(String attribute): 返回Session屬性
Enumeration getAttributeNames(): 返回Session中存在的屬性名
void removeAttribute(String attribute): 移除Session屬性
String getId(): 返回Session的ID。該ID由服務器自動建立,不會重複
long getCreationTime(): 返回Session的建立日期。返回類型爲long,常被轉化爲Date類型,例如:Date createTime = new Date(session.get >CreationTime())
long getLastAccessedTime(): 返回Session的最後活躍時間。返回類型爲long
int getMaxInactiveInterval(): 返回Session的超時時間。單位爲秒。超過該時間沒有訪問,服務器認爲該Session失效
void setMaxInactiveInterval(int second): 設置Session的>超時時間。單位爲秒
void putValue(String attribute, Object value): 不推薦的方法。已經被 setAttribute(String attribute, Object Value)替代
Object getValue(String attribute): 不被推薦的方法。已經被 getAttribute(String attr)替代
boolean isNew(): 返回該Session是不是>新建立的
void invalidate(): 使該Session失效
[1] Session須要使用Cookie做爲識別標誌
雖然Session保存在服務器,對客戶端是透明的,它的正常運行仍然須要客戶端瀏覽器的支持。這是由於Session須要使用Cookie做爲識別標誌。
如何識別?以下識別!
服務器 -----[ Cookie: JSESSIONID with 」session id「 ]-----> 客戶端
Session依據該Cookie來識別是否爲同一用戶。
HTTP協議是無狀態的,Session不能依據HTTP鏈接來判斷是否爲同一客戶,所以服務器向客戶端瀏覽器發送一個名爲JSESSIONID的Cookie,它的值爲該Session的id(也就是HttpSession.getId()的返回值)。
[2] 是否共享 Session
狀況1:同一機器的兩個瀏覽器窗口訪問服務器時,會生成兩個不一樣的Session。
狀況2:可是由瀏覽器窗口內的連接、腳本等打開的新窗口(也就是說不是雙擊桌面瀏覽器圖標等打開的窗口)除外。這類子窗口會共享父窗口的Cookie,所以會共享一個Session。
[3] URL地址重寫是對客戶端不支持Cookie的解決方案。
Step 1,URL地址重寫的原理是將該用戶Session的id信息重寫到URL地址中。
Step 2,服務器可以解析重寫後的URL獲取Session的id。
這樣即便客戶端不支持Cookie,也可使用Session來記錄用戶狀態。
* 若是客戶端支持Cookie,生成原URL地址;
* 若是不支持Cookie,傳回重寫後的帶有jsessionid字符串的地址。
[4] Logout 刪除 session
除非程序通知服務器刪除一個session,不然服務器會一直保留,程序通常都是在用戶作 log off 的時候發個指令去刪除 session。
[5] 經過 cookie 洞察 session
瀏覽器歷來不會主動在關閉以前通知服務器它將要關閉,所以服務器根本不會有機會知道瀏覽器已經關閉。
之因此會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個 session id就消失了,再次鏈接服務器時也就沒法找到原來的session。
若是服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求頭,把原來的session id發送給服務器,則再次打開瀏覽器仍然可以找到原來的session。
既然WAP上大部分的客戶瀏覽器都不支持Cookie,索性禁止Session使用Cookie,統一使用URL地址重寫會更好一些。
5、Cookie與Session的區別
- cookie數據存放在客戶的瀏覽器上,session數據放在服務器上;
- cookie不是很安全,別人能夠分析存放在本地的COOKIE並進行COOKIE欺騙,考慮到安全應當使用session;
- session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能。考慮到減輕服務器性能方面,應當使用COOKIE;
- 單個cookie在客戶端的限制是3K,就是說一個站點在客戶端存放的COOKIE不能超過3K;
Cookie和Session的方案雖然分別屬於客戶端和服務端,可是服務端的session的實現對客戶端的cookie有依賴關係的,
上面我講到服務端執行session機制時候會生成session的id值,這個id值會發送給客戶端,客戶端每次請求都會把這個id值放到http請求的頭部發送給服務端,而這個id值在客戶端會保存下來,保存的容器就是cookie,
所以當咱們徹底禁掉瀏覽器的cookie的時候,服務端的session也會不能正常使用。