http,session,cookie
生活随笔
收集整理的這篇文章主要介紹了
http,session,cookie
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
HTTP Session
一、淺析
HTTP協議(http://www.w3.org/Protocols/)是“一次性單向”協議。
服務端不能主動連接客戶端,只能被動等待并答復客戶端請求。客戶端連接服務端,發出一個HTTP Request,服務端處理請求,并且返回一個HTTP Response給客戶端,本次HTTP Request-Response Cycle結束。
我們看到,HTTP協議本身并不能支持服務端保存客戶端的狀態信息。于是,Web Server中引入了session的概念,用來保存客戶端的狀態信息。
這里用一個形象的比喻來解釋session的工作方式。假設Web Server是一個商場的存包處,HTTP Request是一個顧客,第一次來到存包處,管理員把顧客的物品存放在某一個柜子里面(這個柜子就相當于Session),然后把一個號碼牌交給這個顧客,作為取包憑證(這個號碼牌就是Session ID)。顧客(HTTP Request)下一次來的時候,就要把號碼牌(Session ID)交給存包處(Web Server)的管理員。管理員根據號碼牌(Session ID)找到相應的柜子(Session),根據顧客(HTTP Request)的請求,Web Server可以取出、更換、添加柜子(Session)中的物品,Web Server也可以讓顧客(HTTP Request)的號碼牌和號碼牌對應的柜子(Session)失效。顧客(HTTP Request)的忘性很大,管理員在顧客回去的時候(HTTP Response)都要重新提醒顧客記住自己的號碼牌(Session ID)。這樣,顧客(HTTP Request)下次來的時候,就又帶著號碼牌回來了。
Session ID實際上是在客戶端和服務端之間通過HTTP Request和HTTP Response傳來傳去的。號碼牌(Session ID)必須包含在HTTP Request里面。關于HTTP Request的具體格式,請參見HTTP協議(http://www.w3.org/Protocols/)。這里只做一個簡單的介紹。
在Java Web Server(即Servlet/JSP Server)中,Session ID用jsessionid表示(請參見Servlet規范)。
HTTP Request一般由3部分組成:
(1)Request Line
這一行由HTTP Method(如GET或POST)、URL、和HTTP版本號組成。
例如,GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
GET http://www.google.com/search?q=Tomcat HTTP/1.1
POST http://www.google.com/search HTTP/1.1
GET http://www.somsite.com/menu.do;jsessionid=1001 HTTP/1.1
?
(2)Request Headers
這部分定義了一些重要的頭部信息,如,瀏覽器的種類,語言,類型。Request Headers中還可以包括Cookie的定義。例如:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
Accept-Language: en-us
Cookie: jsessionid=1001
?
(3)Message Body
如果HTTP Method是GET,那么Message Body為空。
如果HTTP Method是POST,說明這個HTTP Request是submit一個HTML Form的結果,
那么Message Body為HTML Form里面定義的Input屬性。例如,
user=guest
password=guest
jsessionid=1001
主意,如果把HTML Form元素的Method屬性改為GET。那么,Message Body為空,所有的Input屬性都會加在URL的后面。你在瀏覽器的URL地址欄中會看到這些屬性,類似于
http://www.somesite/login.do?user=guest&password=guest&jsessionid=1001
?
從理論上來說,這3個部分(Request URL,Cookie Header, Message Body)都可以用來存放Session ID。由于Message Body方法必須需要一個包含Session ID的HTML Form,所以這種方法不通用。
一般用來實現Session的方法有兩種:
(1)URL重寫。
Web Server在返回Response的時候,檢查頁面中所有的URL,包括所有的連接,和HTML Form的Action屬性,在這些URL后面加上“;jsessionid=XXX”。
下一次,用戶訪問這個頁面中的URL。jsessionid就會傳回到Web Server。
(2)Cookie。
如果客戶端支持Cookie,Web Server在返回Response的時候,在Response的Header部分,加入一個“set-cookie: jsessionid=XXXX”header屬性,把jsessionid放在Cookie里傳到客戶端。
客戶端會把Cookie存放在本地文件里,下一次訪問Web Server的時候,再把Cookie的信息放到HTTP Request的“Cookie”header屬性里面,這樣jsessionid就隨著HTTP Request返回給Web Server。
二、相關資料
前面是我自作聰明的一段個人淺見,下面我來找點權威資料支持。
http://www.w3.org/Protocols/
?
Use of HTTP State Management (RFC 2964).
ftp://ftp.rfc-editor.org/in-notes/rfc2964.txt
?
這個文件是定義“HTTP State Management”擴展協議部分。里面有這么一段,
It's important to realize that similar capabilities may also be??? achieved using the "bare" HTTP protocol, and/or dynamically-generated
HTML, without the State Management extensions.? For example, state information can be transmitted from the service to the user by??? embedding a session identifier in one or more URLs which appear in HTTP redirects, or dynamically generated HTML; and the state information may be returned from the user to the service when such URLs appear in a GET or POST request.? HTML forms can also be used to pass state information from the service to the user and back, without the user being aware of this happening.
?
這段話的意思是說,不用這個 “HTTP State Management”擴展協議部分,我們也可以用“純粹”的HTTP協議實現Session -- 比如URL重寫,HTML Form等。
這里面沒有提到Cookie。因為“HTTP State Management” 擴展協議部分本身包括了關于Cookie的內容。這一點可以通過
HTTP State Management Mechanism (RFC 2965),
ftp://ftp.rfc-editor.org/in-notes/rfc2965.txt
看出來。
?
STATE AND SESSIONS
This document describes a way to create stateful sessions with HTTP??? requests and responses.? Currently, HTTP servers respond to each??? client request without relating that request to previous or??? subsequent requests; the state management mechanism allows clients??? and servers that wish to exchange state information to place HTTP??? requests and responses within a larger context, which we term a??? "session".? This context might be used to create, for example, a??? "shopping cart", in which user selections can be aggregated before??? purchase, or a magazine browsing system, in which a user's previous??? reading affects which offerings are presented.
Neither clients nor servers are required to support cookies.? A??? server MAY refuse to provide content to a client that does not return??? the cookies it sends.
?
后面還給出了例子(其中的漢語部分是我加的)。
?
4.1? Example 1
Most detail of request and response headers has been omitted.? Assume
the user agent has no stored cookies.
?
????? 1. User Agent -> Server
?
??????? POST /acme/login HTTP/1.1
??????? [form data]
?
??????? User identifies self via a form.
?
????? 2. Server -> User Agent
?
??????? HTTP/1.1 200 OK
??????? Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
?
??????? Cookie reflects user's identity.
(這里面的 Customer="WILE_E_COYOTE" 應該就是從Form Data里面來的,這時候又傳回給了客戶端)
?
????? 3. User Agent -> Server
?
??????? POST /acme/pickitem HTTP/1.1
??????? Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
??????? [form data]
?
??????? User selects an item for "shopping basket".
?
????? 4. Server -> User Agent
?
??????? HTTP/1.1 200 OK
??????? Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
??????????????? Path="/acme"
?
??????? Shopping basket contains an item.
(這個火箭發射器顯然也是從Form Data來的。但為什么Part_Number="Rocket_Launcher_0001"也需要傳回給客戶端?
Customer="WILE_E_COYOTE"; 應該是在傳統的”Set-Cookie”里面傳回給客戶端的。” Set-Cookie2” 的作用應該是向Cookie里面添加東西。)
?
????? 5. User Agent -> Server
?
??????? POST /acme/shipping HTTP/1.1
??????? Cookie: $Version="1";
??????????????? Customer="WILE_E_COYOTE"; $Path="/acme";
??????????????? Part_Number="Rocket_Launcher_0001"; $Path="/acme"
??????? [form data]
?
??????? User selects shipping method from form.
?
(客戶傳給服務器的Cookie里面包括了Customer和Part_Number)
?
????? 6. Server -> User Agent
?
??????? HTTP/1.1 200 OK
??????? Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme"
?
??????? New cookie reflects shipping method.
?
????? 7. User Agent -> Server
?
??????? POST /acme/process HTTP/1.1
??????? Cookie: $Version="1";
??????????????? Customer="WILE_E_COYOTE"; $Path="/acme";
??????????????? Part_Number="Rocket_Launcher_0001"; $Path="/acme";
??????????????? Shipping="FedEx"; $Path="/acme"
??????? [form data]
?
?
??????? User chooses to process order.
?
????? 8. Server -> User Agent
?
??????? HTTP/1.1 200 OK
?
??????? Transaction is complete.
?
?? The user agent makes a series of requests on the origin server, after each of which it receives a new cookie.? All the cookies have the same Path attribute and (default) domain.? Because the request-URIs all path-match /acme, the Path attribute of each cookie, each request contains all the cookies received so far.
(看到這里,我才大致明白,原來那個$Path="/acme" 大致起著 JSessionID的作用)
?
三、Tomcat5的HTTP Session實現
下面我們來看Tomcat5的源代碼如何支持HTTP 1.1 Session。
我們可以用jsessionid, Set-Cookie等關鍵字搜索Tomcat5源代碼。
?
首先,我們來看常量定義:
org.apache.catalina.Globals
?
??? /**
???? * The name of the cookie used to pass the session identifier back
???? * and forth with the client.
???? */
??? public static final String SESSION_COOKIE_NAME = "JSESSIONID";
?
?
??? /**
???? * The name of the path parameter used to pass the session identifier
???? * back and forth with the client.
???? */
public static final String SESSION_PARAMETER_NAME = "jsessionid";
?
Cookie里面用大寫的JSESSIONID,URL后綴用的是小寫的jsessionid。
Session 的具體實現類是org.apache.catalina.session.StandardSession。一個Tomcat Server的所有Session都由一個Manager(擁有一個Context)統一管理。我估計有一個 Session Listener 專門管理Cluster之間的Session數據復制,具體的我沒有追查下去。
?
另外幾個重要的相關類是org.apache.coyote.tomcat5包下面的CoyoteRequest , CoyoteResponse, CoyoteAdapter三個類。
?
org.apache.coyote.tomcat5.CoyoteResponse類的toEncoded()方法支持URL重寫。
String toEncoded(String url, String sessionId) {
…
??????? StringBuffer sb = new StringBuffer(path);
??????? if( sb.length() > 0 ) { // jsessionid can't be first.
??????????? sb.append(";jsessionid=");
??????????? sb.append(sessionId);
??????? }
??????? sb.append(anchor);
??????? sb.append(query);
??????? return (sb.toString());
}
?
我們來看org.apache.coyote.tomcat5.CoyoteRequest的兩個方法configureSessionCookie()
doGetSession()用Cookie支持jsessionid.
?
??? /**
???? * Configures the given JSESSIONID cookie.
???? *
???? * @param cookie The JSESSIONID cookie to be configured
???? */
??? protected void configureSessionCookie(Cookie cookie) {
?????? …
??? }
?
??? HttpSession doGetSession(boolean create){
????? …
??????? // Creating a new session cookie based on that session
??????? if ((session != null) && (getContext() != null)
?????????????? && getContext().getCookies()) {
??????????? Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,
?????????????????????????????????????? session.getId());
??????????? configureSessionCookie(cookie);
??????????? ((HttpServletResponse) response).addCookie(cookie);
??????? }
????? …
??? }
?
四、More
HTTP Session的協議、規范、實現大概就是這些。
另外,在frameset中使用Session的情況有些復雜,不同環境表現可能不同。
其余相關的概念有“單點登錄”(Sing Sign On – SSO), Domain, Cluster, Proxy, Cache等。
一、淺析
HTTP協議(http://www.w3.org/Protocols/)是“一次性單向”協議。
服務端不能主動連接客戶端,只能被動等待并答復客戶端請求。客戶端連接服務端,發出一個HTTP Request,服務端處理請求,并且返回一個HTTP Response給客戶端,本次HTTP Request-Response Cycle結束。
我們看到,HTTP協議本身并不能支持服務端保存客戶端的狀態信息。于是,Web Server中引入了session的概念,用來保存客戶端的狀態信息。
這里用一個形象的比喻來解釋session的工作方式。假設Web Server是一個商場的存包處,HTTP Request是一個顧客,第一次來到存包處,管理員把顧客的物品存放在某一個柜子里面(這個柜子就相當于Session),然后把一個號碼牌交給這個顧客,作為取包憑證(這個號碼牌就是Session ID)。顧客(HTTP Request)下一次來的時候,就要把號碼牌(Session ID)交給存包處(Web Server)的管理員。管理員根據號碼牌(Session ID)找到相應的柜子(Session),根據顧客(HTTP Request)的請求,Web Server可以取出、更換、添加柜子(Session)中的物品,Web Server也可以讓顧客(HTTP Request)的號碼牌和號碼牌對應的柜子(Session)失效。顧客(HTTP Request)的忘性很大,管理員在顧客回去的時候(HTTP Response)都要重新提醒顧客記住自己的號碼牌(Session ID)。這樣,顧客(HTTP Request)下次來的時候,就又帶著號碼牌回來了。
Session ID實際上是在客戶端和服務端之間通過HTTP Request和HTTP Response傳來傳去的。號碼牌(Session ID)必須包含在HTTP Request里面。關于HTTP Request的具體格式,請參見HTTP協議(http://www.w3.org/Protocols/)。這里只做一個簡單的介紹。
在Java Web Server(即Servlet/JSP Server)中,Session ID用jsessionid表示(請參見Servlet規范)。
HTTP Request一般由3部分組成:
(1)Request Line
這一行由HTTP Method(如GET或POST)、URL、和HTTP版本號組成。
例如,GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
GET http://www.google.com/search?q=Tomcat HTTP/1.1
POST http://www.google.com/search HTTP/1.1
GET http://www.somsite.com/menu.do;jsessionid=1001 HTTP/1.1
?
(2)Request Headers
這部分定義了一些重要的頭部信息,如,瀏覽器的種類,語言,類型。Request Headers中還可以包括Cookie的定義。例如:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
Accept-Language: en-us
Cookie: jsessionid=1001
?
(3)Message Body
如果HTTP Method是GET,那么Message Body為空。
如果HTTP Method是POST,說明這個HTTP Request是submit一個HTML Form的結果,
那么Message Body為HTML Form里面定義的Input屬性。例如,
user=guest
password=guest
jsessionid=1001
主意,如果把HTML Form元素的Method屬性改為GET。那么,Message Body為空,所有的Input屬性都會加在URL的后面。你在瀏覽器的URL地址欄中會看到這些屬性,類似于
http://www.somesite/login.do?user=guest&password=guest&jsessionid=1001
?
從理論上來說,這3個部分(Request URL,Cookie Header, Message Body)都可以用來存放Session ID。由于Message Body方法必須需要一個包含Session ID的HTML Form,所以這種方法不通用。
一般用來實現Session的方法有兩種:
(1)URL重寫。
Web Server在返回Response的時候,檢查頁面中所有的URL,包括所有的連接,和HTML Form的Action屬性,在這些URL后面加上“;jsessionid=XXX”。
下一次,用戶訪問這個頁面中的URL。jsessionid就會傳回到Web Server。
(2)Cookie。
如果客戶端支持Cookie,Web Server在返回Response的時候,在Response的Header部分,加入一個“set-cookie: jsessionid=XXXX”header屬性,把jsessionid放在Cookie里傳到客戶端。
客戶端會把Cookie存放在本地文件里,下一次訪問Web Server的時候,再把Cookie的信息放到HTTP Request的“Cookie”header屬性里面,這樣jsessionid就隨著HTTP Request返回給Web Server。
二、相關資料
前面是我自作聰明的一段個人淺見,下面我來找點權威資料支持。
http://www.w3.org/Protocols/
?
Use of HTTP State Management (RFC 2964).
ftp://ftp.rfc-editor.org/in-notes/rfc2964.txt
?
這個文件是定義“HTTP State Management”擴展協議部分。里面有這么一段,
It's important to realize that similar capabilities may also be??? achieved using the "bare" HTTP protocol, and/or dynamically-generated
HTML, without the State Management extensions.? For example, state information can be transmitted from the service to the user by??? embedding a session identifier in one or more URLs which appear in HTTP redirects, or dynamically generated HTML; and the state information may be returned from the user to the service when such URLs appear in a GET or POST request.? HTML forms can also be used to pass state information from the service to the user and back, without the user being aware of this happening.
?
這段話的意思是說,不用這個 “HTTP State Management”擴展協議部分,我們也可以用“純粹”的HTTP協議實現Session -- 比如URL重寫,HTML Form等。
這里面沒有提到Cookie。因為“HTTP State Management” 擴展協議部分本身包括了關于Cookie的內容。這一點可以通過
HTTP State Management Mechanism (RFC 2965),
ftp://ftp.rfc-editor.org/in-notes/rfc2965.txt
看出來。
?
STATE AND SESSIONS
This document describes a way to create stateful sessions with HTTP??? requests and responses.? Currently, HTTP servers respond to each??? client request without relating that request to previous or??? subsequent requests; the state management mechanism allows clients??? and servers that wish to exchange state information to place HTTP??? requests and responses within a larger context, which we term a??? "session".? This context might be used to create, for example, a??? "shopping cart", in which user selections can be aggregated before??? purchase, or a magazine browsing system, in which a user's previous??? reading affects which offerings are presented.
Neither clients nor servers are required to support cookies.? A??? server MAY refuse to provide content to a client that does not return??? the cookies it sends.
?
后面還給出了例子(其中的漢語部分是我加的)。
?
4.1? Example 1
Most detail of request and response headers has been omitted.? Assume
the user agent has no stored cookies.
?
????? 1. User Agent -> Server
?
??????? POST /acme/login HTTP/1.1
??????? [form data]
?
??????? User identifies self via a form.
?
????? 2. Server -> User Agent
?
??????? HTTP/1.1 200 OK
??????? Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
?
??????? Cookie reflects user's identity.
(這里面的 Customer="WILE_E_COYOTE" 應該就是從Form Data里面來的,這時候又傳回給了客戶端)
?
????? 3. User Agent -> Server
?
??????? POST /acme/pickitem HTTP/1.1
??????? Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
??????? [form data]
?
??????? User selects an item for "shopping basket".
?
????? 4. Server -> User Agent
?
??????? HTTP/1.1 200 OK
??????? Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
??????????????? Path="/acme"
?
??????? Shopping basket contains an item.
(這個火箭發射器顯然也是從Form Data來的。但為什么Part_Number="Rocket_Launcher_0001"也需要傳回給客戶端?
Customer="WILE_E_COYOTE"; 應該是在傳統的”Set-Cookie”里面傳回給客戶端的。” Set-Cookie2” 的作用應該是向Cookie里面添加東西。)
?
????? 5. User Agent -> Server
?
??????? POST /acme/shipping HTTP/1.1
??????? Cookie: $Version="1";
??????????????? Customer="WILE_E_COYOTE"; $Path="/acme";
??????????????? Part_Number="Rocket_Launcher_0001"; $Path="/acme"
??????? [form data]
?
??????? User selects shipping method from form.
?
(客戶傳給服務器的Cookie里面包括了Customer和Part_Number)
?
????? 6. Server -> User Agent
?
??????? HTTP/1.1 200 OK
??????? Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme"
?
??????? New cookie reflects shipping method.
?
????? 7. User Agent -> Server
?
??????? POST /acme/process HTTP/1.1
??????? Cookie: $Version="1";
??????????????? Customer="WILE_E_COYOTE"; $Path="/acme";
??????????????? Part_Number="Rocket_Launcher_0001"; $Path="/acme";
??????????????? Shipping="FedEx"; $Path="/acme"
??????? [form data]
?
?
??????? User chooses to process order.
?
????? 8. Server -> User Agent
?
??????? HTTP/1.1 200 OK
?
??????? Transaction is complete.
?
?? The user agent makes a series of requests on the origin server, after each of which it receives a new cookie.? All the cookies have the same Path attribute and (default) domain.? Because the request-URIs all path-match /acme, the Path attribute of each cookie, each request contains all the cookies received so far.
(看到這里,我才大致明白,原來那個$Path="/acme" 大致起著 JSessionID的作用)
?
三、Tomcat5的HTTP Session實現
下面我們來看Tomcat5的源代碼如何支持HTTP 1.1 Session。
我們可以用jsessionid, Set-Cookie等關鍵字搜索Tomcat5源代碼。
?
首先,我們來看常量定義:
org.apache.catalina.Globals
?
??? /**
???? * The name of the cookie used to pass the session identifier back
???? * and forth with the client.
???? */
??? public static final String SESSION_COOKIE_NAME = "JSESSIONID";
?
?
??? /**
???? * The name of the path parameter used to pass the session identifier
???? * back and forth with the client.
???? */
public static final String SESSION_PARAMETER_NAME = "jsessionid";
?
Cookie里面用大寫的JSESSIONID,URL后綴用的是小寫的jsessionid。
Session 的具體實現類是org.apache.catalina.session.StandardSession。一個Tomcat Server的所有Session都由一個Manager(擁有一個Context)統一管理。我估計有一個 Session Listener 專門管理Cluster之間的Session數據復制,具體的我沒有追查下去。
?
另外幾個重要的相關類是org.apache.coyote.tomcat5包下面的CoyoteRequest , CoyoteResponse, CoyoteAdapter三個類。
?
org.apache.coyote.tomcat5.CoyoteResponse類的toEncoded()方法支持URL重寫。
String toEncoded(String url, String sessionId) {
…
??????? StringBuffer sb = new StringBuffer(path);
??????? if( sb.length() > 0 ) { // jsessionid can't be first.
??????????? sb.append(";jsessionid=");
??????????? sb.append(sessionId);
??????? }
??????? sb.append(anchor);
??????? sb.append(query);
??????? return (sb.toString());
}
?
我們來看org.apache.coyote.tomcat5.CoyoteRequest的兩個方法configureSessionCookie()
doGetSession()用Cookie支持jsessionid.
?
??? /**
???? * Configures the given JSESSIONID cookie.
???? *
???? * @param cookie The JSESSIONID cookie to be configured
???? */
??? protected void configureSessionCookie(Cookie cookie) {
?????? …
??? }
?
??? HttpSession doGetSession(boolean create){
????? …
??????? // Creating a new session cookie based on that session
??????? if ((session != null) && (getContext() != null)
?????????????? && getContext().getCookies()) {
??????????? Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,
?????????????????????????????????????? session.getId());
??????????? configureSessionCookie(cookie);
??????????? ((HttpServletResponse) response).addCookie(cookie);
??????? }
????? …
??? }
?
四、More
HTTP Session的協議、規范、實現大概就是這些。
另外,在frameset中使用Session的情況有些復雜,不同環境表現可能不同。
其余相關的概念有“單點登錄”(Sing Sign On – SSO), Domain, Cluster, Proxy, Cache等。
總結
以上是生活随笔為你收集整理的http,session,cookie的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iPhone系统常用文件夹位置
- 下一篇: 苹果手表5代防水吗 5代防水功能介绍