Session,Cookie,jsessionid,Url重写
?
在一些投票之類的場合,我們往往因為公平的原則要求每人只能投一票,在一些WEB開發中也有類似的情況,這時候我們通常會使用COOKIE來實現,例如如下的代碼:
< % cookie[]cookies = request.getCookies();
if (cookies.lenght == 0 || cookies == null){
doStuffForNewbie();
//沒有訪問過
}else{
doStuffForReturnVisitor(); //已經訪問過了
}
% >
?
這是很淺顯易懂的道理,檢測COOKIE的存在,如果存在說明已經運行過寫入COOKIE的代碼了,然而運行以上的代碼后,無論何時結果都是執行doStuffForReturnVisitor(),通過控制面板-Internet選項-設置-察看文件卻始終看不到生成的cookie文件,奇怪,代碼明明沒有問題,不過既然有cookie,那就顯示出來看看。
cookie[]cookies = request.getCookies();
if (cookies.lenght == 0 || cookies == null)
out.println("Has not visited this website");
}else{
for (int i = 0; i < cookie.length; i++){
out.println("cookie name:" + cookies[i].getName() + "cookie value:" +
cookie[i].getValue());
}
}
?
運行結果:
cookie name:JSESSIONID cookie value:KWJHUG6JJM65HS2K6
?
為什么會有cookie呢,大家都知道,http是無狀態的協議,客戶每次讀取web頁面時,服務器都打開新的會話,而且服務器也不會自動維護客戶的上下文信息,那么要怎么才能實現網上商店中的購物車呢,session就是一種保存上下文信息的機制,它是針對每一個用戶的,變量的值保存在服務器端,通過SessionID來區分不同的客戶,session是以cookie或URL重寫為基礎的,默認使用cookie來實現,系統會創造一個名為JSESSIONID的輸出cookie,我們叫做session cookie,以區別persistent cookies,也就是我們通常所說的cookie,注意session cookie是存儲于瀏覽器內存中的,并不是寫到硬盤上的,這也就是我們剛才看到的JSESSIONID,我們通常情是看不到JSESSIONID的,但是當我們把瀏覽器的cookie禁止后,web服務器會采用URL重寫的方式傳遞Sessionid,我們就可以在地址欄看到sessionid=KWJHUG6JJM65HS2K6之類的字符串。
?
明白了原理,我們就可以很容易的分辨出persistent cookies和session cookie的區別了,網上那些關于兩者安全性的討論也就一目了然了,session cookie針對某一次會話而言,會話結束session cookie也就隨著消失了,而persistent cookie只是存在于客戶端硬盤上的一段文本(通常是加密的),而且可能會遭到cookie欺騙以及針對cookie的跨站腳本攻擊,自然不如session cookie安全了。
?
通常session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的sessionid,這樣我們信息共享的目的就達不到了,此時我們可以先把sessionid保存在persistent cookie中,然后在新窗口中讀出來,就可以得到上一個窗口SessionID了,這樣通過session cookie和persistent cookie的結合我們就實現了跨窗口的session tracking(會話跟蹤)。
?
?? ? ?在一些web開發的書中,往往只是簡單的把Session和cookie作為兩種并列的http傳送信息的方式,session cookies位于服務器端,persistent cookie位于客戶端,可是session又是以cookie為基礎的,明白的兩者之間的聯系和區別,我們就不難選擇合適的技術來開發web service了。
?
?
cookie和session機制之間的區別與聯系
?? ? ??具體來說cookie機制采用的是在客戶端保持狀態的方案。它是在用戶端的會話狀態的存貯機制,他需要用戶打開客戶端的cookie支持。cookie的作用就是為了解決HTTP協議無狀態的缺陷所作的努力.
?
?? ? ??而session機制采用的是一種在客戶端與服務器之間保持狀態的解決方案。同時我們也看到,由于采用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助于cookie機制來達到保存標識的目的。而session提供了方便管理全局變量的方式
?
session是針對每一個用戶的,變量的值保存在服務器上,用一個sessionID來區分是哪個用戶session變量,這個值是通過用戶的瀏覽器在訪問的時候返回給服務器,當客戶禁用cookie時,這個值也可能設置為由get來返回給服務器。
?
就安全性來說:當你訪問一個使用session 的站點,同時在自己機子上建立一個cookie,建議在服務器端的SESSION機制更安全些.因為它不會任意讀取客戶存儲的信息。
?
正統的cookie分發是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由瀏覽器按照一定的原則在后臺自動發送給服務器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用范圍大于等于將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器。
?
從網絡服務器觀點看所有HTTP請求都獨立于先前請求。就是說每一個HTTP響應完全依賴于相應請求中包含的信息狀態管理機制克服了HTTP的一些限制并允許網絡客戶端及服務器端維護請求間的關系。在這種關系維持的期間叫做會話(session)。
?
Cookies是服務器在本地機器上存儲的小段文本并隨每一個請求發送至同一個服務器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie規范。網絡服務器用HTTP頭向客戶端發送cookies,在客戶終端,瀏覽器解析這些cookies并將它們保存為一個本地文件,它會自動將同一服務器的任何請求縛上這些cookies。
?
?? ? ? cookie的內容主要包括:名字,值,過期時間,路徑和域。路徑與域一起構成cookie的作用范圍。若不設置過期時間,則表示這個cookie的生命期為瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失。這種生命期為瀏覽器會話期的cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存里,當然這種行為并不是規范規定的。若設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉后再次打開瀏覽器,這些cookie仍然有效直到超過設定的過期時間。存儲在硬盤上的cookie可以在不同的瀏覽器進程間共享,比如兩個IE窗口。而對于保存在內存里的cookie,不同的瀏覽器有不同的處理方式。
?
?? ? ? ?session機制。session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。
?
當程序需要為某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端創建過session,服務器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。
?
保存這個session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發揮給服務器。一般這個cookie的名字都是類似于SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。
?
經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的后面。還有一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。比如:
?
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
?
什么是Url重寫?
?
服務器也可以通過URL重寫的方式來傳遞SessionID的值,因此不是完全依賴Cookie。如果客戶端Cookie禁用,則服務器可以自動通過重寫URL的方式來保存Session的值,并且這個過程對程序員透明。
?
可以試一下,即使不寫Cookie,在使用request.getCookies();取出的Cookie數組的長度也是1,而這個Cookie的名字就是JSESSIONID,還有一個很長的二進制的字符串,是SessionID的值。
?
實質上 URL 重寫是通過向 URL 連接添加參數,并把 session ID 作為值包含在連接中。然而,為使這生效,你需要為你的 servlet 響應部分的每個連接添加 session ID.
?
利用Url進行Session重寫如何實現?
?
JSP實現
把 session ID 加到一個連接可以使用一對方法來簡化:response.encodeURL() 使 URL包含 session ID,如果你需要使用重定向,可以使用 response.encodeRedirectURL ()來對 URL 進行編碼。encodeURL () 及 encodeRedirectedURL () 方法首先判斷 cookie是否被瀏覽器支持;如果支持,則參數 URL 被原樣返回,session ID 將通過 cookies 來維持。
代碼示例:
不使用Url重寫:<a href=http://wwww.myserver.com/servelet/user;userName=awaysrain>Link</a>
使用Url重寫:通過HttpServletResponse接口中的encodeURL()方法編碼.
String myURL = response.encodeURL(http://wwww.myserver.com/servelet/user);
<a href= <%=myURL%> _fcksavedurl=" <%=myURL%>" _fcksavedurl=" <%=myURL%>" _fcksavedurl=" <%=myURL%>" >
?
JSTL實現
<c:url>可以為會話管理重寫 URL
<a href="<c:url value='/content/sitemap.jsp'/>">View sitemap</a>
?
?
Struts實現:
struts配置文件中:設置屬性redirect, contextRelative
?
<forward name="listArticlesForBlog"
path="/template/listArticlesForBlog.jsp"
redirect="true"
contextRelative="true"/>
?
最后一個比較搞的問題:
那么在瀏覽器允許cookie的情況下,不要求瀏覽器關閉cookie的情況下使用
url重寫如何實現?
http://tomcat.apache.org/tomcat-5.5-doc/config/context.html
Context支持cookies參數。 設置cookies="false",強制只從url解析sessionid。
?原文地址 ? http://justsee.iteye.com/blog/831730
轉載于:https://www.cnblogs.com/shaohaixiong/p/4608934.html
總結
以上是生活随笔為你收集整理的Session,Cookie,jsessionid,Url重写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java】 大话数据结构(1) 线性
- 下一篇: bzoj 1999: [Noip2007