Cookie和Session都是為了保持使用者的存取狀態,一方面為了方便業務實現,另一方面為了簡化服務端的程式設計,提高存取效能。 Cookie是客戶端(也就是瀏覽器端)的技術,設定了Cookie之後,每次存取服務端,請求中都會帶上Cookie;Session是服務端技術,在服務端儲存使用者的存取資訊。
使用Cookie傳遞訊息,隨著Cookie個數增多和訪問量增大,它佔用的頻寬會越來越大;使用Session保存訊息,最大的弱點就是不容易在多台伺服器之間共享。
1 Cookie
通俗地講,當使用者使用HTTP存取伺服器時,伺服器會將一些鍵值對資訊傳回給客戶端瀏覽器,並且給這些資料加上一些限制條件,在符合限制條件情況下使用者下次造訪伺服器時,會帶上先前設定的Cookie鍵值對資訊。當該使用者輸入 URL 時,瀏覽器會在本機硬碟上尋找與該 URL 相關的 Cookie。如果該 Cookie 存在,瀏覽器便將該 Cookie 與頁面請求一起傳送到您的網站。
Cookie 與網站關聯,而不是與特定的頁面關聯。因此,無論使用者要求網站中的哪一個頁面,瀏覽器和伺服器都將交換 Cookie 資訊。當使用者造訪不同網站時,各個網站可能會傳送一個 Cookie 到使用者的瀏覽器;瀏覽器會分別儲存所有 Cookie。
Cookie屬性項目
目前Cookie有2個版本,Version 0 和 Version 1,它們有2種設定回應頭標識,分別是"Set-Cookie"和"Set-Cookie2"。
Cookie 0屬性值
Cookie 1屬性值
Java中使用CookieCookie
rrrereee建立的Cookie的name和value不能為非ASSIC字符,如果是中文,可以透過RRLEncoder將其編碼,否則會拋出java.lang.IllegalArgumentException異常。
•多出現多個name和value值時,它們實在同一個"Cookie"頭中的。 •Cookies的值中可以保存除了「;」以外的標點符號。但是不能保存漢字。儲存漢字會出現亂碼。Cookie的一些限制
Cookie是HTTP頭中的一個字段,HTTP本身對該字段沒有限制,但是Cookie最終存儲在瀏覽器中,不同的瀏覽器對Cookie的存儲有一些限制,如下表所示:
如果試圖存放更多Cookie,則最舊的Cookie 便會被丟棄。
2 Session
Session解決了Cookie增加時會增加客戶端與伺服器的資料傳輸量問題,同一個客戶端與伺服器互動時,不需要每次都傳回所有的Cookie值,而是只要傳回一個ID值,這個ID是客戶端第一次存取伺服器時產生的,而且每個客戶端是唯一的,這個ID通常是name為JSESSIONID的一個Cookie。
Session是如何基於Cookie工作的呢,可以是基於URL Path Parameter方式;也可以是基於Cookie,如果沒有修改Context容器中的Cookies標識,則預設也是支援的。當瀏覽器不支援Cookie功能時,瀏覽器會將使用者的SessionCookieName重寫到使用者要求的URL參數中,它的傳遞方式如/path/Servlet;name=xxx;name2=xxx2?name3=xxx3。 SessionCookieName如果在web.xml中配置session-config配置項,其cookie-config下的name屬性就是這個SessionCookieName的值。如果沒有配置session-config配置項,預設的SessionCookieNamejiushi “JSESSIONID”。請注意,與Session關聯的Cookie與其他Cookie並沒有什麼不同。如果客戶端也支援Cookie,則Tomcat仍會解析Cookie中的Session ID,並會覆寫URL中的Session ID。
Session如何運作
有了Session ID,服务器就可以创建HttpSession对象了,第一次调用request.getSession()方法,如果没有对应的HttpSession对象,则会创建一个新的,并将这个对象加入到org.apache.catalina.Manager的sessions容器中保存。Manage保存所有的session生命周期,Session过期被回收,服务器关闭,Session被序列化到磁盘。注意,一个客户端对应一个Session对象,这个对象正是保存我们创建的Session值的。
request.getSession()方法调用的StandardSession永远都会存在,即使与这个客户端关联的Session已经过期。如果过期,则会创建一个新的,但是以前设置的Session值将会丢失。
3 Cookie与Session安全性比较
Cookie将保存的数据通过HTTP头部从客户端传到服务端,从服务端再传回到客户端,所有的数据都保存在客户端浏览器中,这些数据都是可以访问到的,甚至可以通过插件添加、修改Cookie,所有Cookie的安全性是比较差的。相比较而言,Session将数据保存在服务器端,安全性高很多,只需要Cookie传回一个Cookie ID就可以,所以Session更适合保存用户隐私和重要的数据。
分布式Session框架
在大型互联网应用中,单用Cookie和Session都是不可行的,因为如果使用Cookie可以很好地解决应用的分布式部署问题,大型互联网应用系统一个应用有上百台机器,而且有很多不同的应用系统协同工作,由于Cookie是将数据存储在用户浏览器中,用户每次访问都会讲数据带回到服务器,也就解决了同一个用户的请求在不同服务器上处理而导致的Cookie不一致问题。
由于应用是一个集群,所以不能将Session都保存在每台服务器的内存中,如果每台服务器有几十万访问用户,服务器内存也容不下,即使容得下,也无法保证该Session同步到其他服务器中,所以共享这些Session需要将它们保存在专门的分布式缓存中,可以随时读取和写入,性能要够好满足要求,如memcache/redis或者淘宝的开源分布式框架Tair都是很好的选择。
表单重复提交问题
网站中有很多地方有重复提交表单问题,为了防止表单重复提交,就要标识用户的每一次访问请求,使得每一次访问请求对服务端来说都是唯一的,为了标识用户的每次请求,可以在用户请求的表单域增加一个隐藏表单项,其值为唯一的token,如:
<form id="form" method="post"> ... <input type=hidden name="token" value="xxx"/> </form>
用户请求表单时生成唯一的token,并且设置到该用户的Session中,等用户提交时检测这个token是否和Session中保存的token一致,如果一致,说明没有重复提交,同时把Session中的token更新成一个新的token值;否则用户提交上来的token已经不是当前请求的合法token,提交失败。
以上所述是小编给大家介绍的Java中Cookie和Session的那些事兒,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对PHP中文网的支持!
更多Java中Cookie和Session的那些事兒相关文章请关注PHP中文网!