第一部分 HTTP協議的內容和特色 html
HTTP(HyperTextTransferProtocol)是超文本傳輸協議的縮寫,它用於傳送WWW方式的數據,關於HTTP協議的詳細內容請參考RFC2616。HTTP是一個屬於應用層的面向對象的協議,因爲其簡捷、快速的方式,適用於分佈式超媒體信息系統。它於1990年提出,通過幾年的使用與發展,獲得不斷地完善和擴展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的規範化工做正在進行之中,並且HTTP-NG(NextGenerationofHTTP)的建議已經提出。今天在實驗室把相關的RFC文檔仔細看了一下,對HTTP協議有了一個詳細的認識,本文將作一個詳細的介紹。數據庫
1 HTTP協議特色及其相關概念瀏覽器
HTTP協議的主要特色可歸納以下:緩存
1.支持客戶/服務器模式。服務器
2.簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、POST。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。網絡
3.靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。session
4.無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。app
5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。編輯器
1.鏈接(Connection):一個傳輸層的實際環流,它是創建在兩個相互通信的應用程序之間。分佈式
2.消息(Message):HTTP通信的基本單位,包括一個結構化的八元組序列並經過鏈接傳輸。
3.請求(Request):一個從客戶端到服務器的請求信息包括應用於資源的方法、資源的標識符和協議的版本號
4.響應(Response):一個從服務器返回的信息包括HTTP協議的版本號、請求的狀態(例如「成功」或「沒找到」)和文檔的MIME類型。
5.資源(Resource):由URI標識的網絡數據對象或服務。
6.實體(Entity):數據資源或來自服務資源的回映的一種特殊表示方法,它可能被包圍在一個請求或響應信息中。一個實體包括實體頭信息和實體的自己內容。
7.客戶機(Client):一個爲發送請求目的而創建鏈接的應用程序。
8.用戶代理(Useragent):初始化一個請求的客戶機。它們是瀏覽器、編輯器或其它用戶工具。
9.服務器(Server):一個接受鏈接並對請求返回信息的應用程序。
10.源服務器(Originserver):是一個給定資源能夠在其上駐留或被建立的服務器。
11.代理(Proxy): 一箇中間程序,它能夠充當一個服務器,也能夠充當一個客戶機,爲其它客戶機創建請求。請求是經過可能的翻譯在內部或通過傳遞到其它的服務器中。一個代理在 發送請求信息以前,必須解釋而且若是可能重寫它。代理常常做爲經過防火牆的客戶機端的門戶,代理還能夠做爲一個幫助應用來經過協議處理沒有被用戶代理完成 的請求。
12.網關(Gateway):一個做爲其它服務器中間媒介的服務器。與代理不一樣的是,網關接受請求就好象對被請求的資源來講它就是源服務器;發出請求的客戶機並無意識到它在同網關打交道。網關常常做爲經過防火牆的服務器端的門戶,網關還能夠做爲一個協議翻譯器以便存取那些存儲在非HTTP系統中的資源。
13.通道(Tunnel):是做爲兩個鏈接中繼的中介程序。一旦激活,通道便被認爲不屬於HTTP通信,儘管通道多是被一個HTTP請求初始化的。當被中繼的鏈接兩端關閉時,通道便消失。當一個門戶(Portal)必須存在或中介(Intermediary)不能解釋中繼的通信時通道被常用。
14.緩存(Cache):反應信息的局域存儲。
2 HTTP協議的運做方式
HTTP協議是基於請求/響應範式的。一個客戶機與服務器創建鏈接後,發送一個請求給服務器,請求方式的格式爲,統一資源標識符、協議版本號,後邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。服務器接到請求後,給予相應的響應信息,其格式爲一個狀態行包括信息的協議版本號、一個成功或錯誤的代碼,後邊是MIME信息包括服務器信息、實體信息和可能的內容。在Internet上,HTTP通信一般發生在TCP/IP鏈接之上。缺省端口是TCP80,但其它的端口也是可用的。但這並不預示着HTTP協議在Internet或其它網絡的其它協議之上才能完成。HTTP只預示着一個可靠的傳輸。
3 HTTP協議的內部操做過程
首先,簡單介紹基於HTTP協議的客戶/服務器模式的信息交換過程,它分四個過程,創建鏈接、發送請求信息、發送響應信息、關閉鏈接。在WWW中,「客戶」與「服務器」是一個相對的概念,只存在於一個特定的鏈接期間,即在某個鏈接中的客戶在另外一個鏈接中可能做爲服務器。WWW服務器運行時,一直在TCP80端口(WWW的缺省端口)監聽,等待鏈接的出現。
1.創建鏈接 鏈接的創建是經過申請套接字(Socket)實現的。客戶打開一個套接字並把它約束在一個端口上,若是成功,就至關於創建了一個虛擬文件。之後就能夠在該虛擬文件上寫數據並經過網絡向外傳送。
2.發送請求打開一個鏈接後,客戶機把請求消息送到服務器的停留端口上,完成提出請求動做。HTTP/1.0 請求消息的格式爲:
請求消息=請求行(通用信息|請求頭|實體頭)CRLF[實體內容]
請求 行=方法 請求URL HTTP版本號 CRLF
方 法=GET|HEAD|POST|擴展方法
U R L=協議名稱+宿主名+目錄與文件名
請求行中的方法描述指定資源中應該執行的動做,經常使用的方法有GET、HEAD和POST。不一樣的請求對象對應GET的結果是不一樣的,對應關係以下:
對象 GET的結果
文件 文件的內容
程序 該程序的執行結果
數據庫查詢 查詢結果
HEAD——要求服務器查找某對象的元信息,而不是對象自己。
POST——從客戶機向服務器傳送數據,在要求服務器和CGI作進一步處理時會用到POST方法。
POST主要用於發送HTML文本中FORM的內容,讓CGI程序處理。
一個請求的例子爲:GEThttp://networking.zju.edu.cn/zju/index.htmHTTP/1.0
頭信息又稱爲元信息,即信息的信息,利用元信息能夠實現有條件的請求或應答。
請求頭——告訴服務器怎樣解釋本次請求,主要包括用戶能夠接受的數據類型、壓縮方法和語言等。
實體頭——實體信息類型、長度、壓縮方法、最後一次修改時間、數據有效期等。
實體——請求或應答對象自己。
3.發送響應
服務器在處理完客戶的請求以後,要向客戶機發送響應消息。
HTTP/1.0的響應消息格式以下:
響應消息=狀態行(通用信息頭|響應頭|實體頭) CRLF 〔實體內容〕
狀態行=HTTP版本號 狀態碼 緣由敘述
響應頭的信息包括:服務程序名,通知客戶請求的URL須要認證,請求的資源什麼時候能使用。
4.關閉鏈接
客戶和服務器雙方均可以經過關閉套接字來結束TCP/IP對話
一般HTTP消息包括客戶機向服務器的請求消息和服務器向客戶機的響應消息。這兩種類型的消息由一個起始行,一個或者多個頭域,一個只是頭域結束的空行和可選的消息體組成。HTTP的頭域包括通用頭,請求頭,響應頭和實體頭四個部分。每一個頭域由一個域名,冒號(:)和域值三部分組成。域名是大小寫無關的,域值前能夠添加任何數量的空格符,頭域能夠被擴展爲多行,在每行開始處,使用至少一個空格或製表符。
第二部分 它的無狀態性質的缺陷及其解決方法
既然HTTP協議的目的在於支持超文本的傳輸,更加廣義一些就是支持資源的傳輸,那麼在客戶端瀏覽器向HTTP服務器發送請求, 繼而HTTP服務器將相應的資源發回給客戶端這樣一個過程當中,不管對於客戶端仍是服務器,都沒有必要記錄這個過程,由於每一次請求和響應都是相對獨立的, 就好像你在自動售貨機前投下硬幣購買商品同樣,誰都不會也不須要記住這樣一個交易過程。通常而言,一個URL對應着惟一的超文本,而HTTP服務器也絕對 公平公正,無論你是Michael,仍是Jordon,它都會根據接收到的URL請求返回相同的超文本。正是由於這樣的惟一性,使得記錄用戶的行爲狀態變 得毫無心義,因此,HTTP協議被設計爲無狀態的鏈接協議符合它自己的需求。
然而,隨着時間的推移,人們發現靜態的HTML着實無聊而乏味,增長動態生成的內容纔會令Web應用程序變得更加有用。因而乎,HTML的語法在不斷膨 脹,其中最重要的是增長了表單(Form);客戶端也增長了諸如腳本處理、DOM處理等功能;對於服務器,則相應的出現了CGI(Common Gateway Interface)以處理包含表單提交在內的動態請求。在這種客戶端與服務器進行動態交互的Web應用程序出現以後,HTTP無狀態的特性嚴重阻礙了這 些應用程序的實現,畢竟交互是須要承前啓後的,簡單的購物車程序也要知道用戶到底在以前選擇了什麼商品。因而,兩種用於保持HTTP鏈接狀態的技術就應運 而生了,一個是Cookie,而另外一個則是Session。
Cookie是經過客戶端保持狀態的解決方案。從定義上來講,Cookie就是由服務器發給客戶端的特殊信息,而這些信息以文本文件的方式存放在客戶端, 而後客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息。讓咱們說得更具體一些:當用戶使用瀏覽器訪問一個支持Cookie的網站的時候,用戶會提 供包括用戶名在內的我的信息而且提交至服務器;接着,服務器在向客戶端回傳相應的超文本的同時也會發回這些我的信息,固然這些信息並非存放在HTTP響 應體(Response Body)中的,而是存放於HTTP響應頭(Response Header);當客戶端瀏覽器接收到來自服務器的響應以後,瀏覽器會將這些信息存放在一個統一的位置,對於Windows操做系統而言,咱們能夠從: [系統盤]:\Documents and Settings\[用戶名]\Cookies目錄中找到存儲的Cookie;自此,客戶端再向服務器發送請求的時候,都會把相應的Cookie再次發回 至服務器。而此次,Cookie信息則存放在HTTP請求頭(Request Header)了。
有了Cookie這樣的技術實現,服務器在接收到來自客戶端瀏覽器的請求以後,就可以經過分析存放於請求頭的Cookie獲得客戶端特有的信息,從而動態 生成與該客戶端相對應的內容。一般,咱們能夠從不少網站的登陸界面中看到「請記住我」這樣的選項,若是你勾選了它以後再登陸,那麼在下一次訪問該網站的時 候就不須要進行重複而繁瑣的登陸動做了,而這個功能就是經過Cookie實現的。
與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,從而再次使用之。正式這樣一個過程,用戶的狀態也就得以保持了。有關Session的內容還比較多,在之後的Post中, 我還將繼續講述。
另外,還有一種Application對象,它和Cookie及Session的區別主要以下圖所示:
它的功能能夠實現對全部用戶的操做,用下面這個例子能夠很容易的理解:
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="utf-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Application和Session的例子</title> </head> <body> <% int applicationCount=1; int sessionCount=1; //若是Application["ApplicationCount"]爲空,即沒有設置該名字的session if(Application["ApplicationCount"]==null) { Application["ApplicationCount"]=1; } else //不然取出之前的ApplicationCount ,並在上面加1 { applicationCount=(int)Application["ApplicationCount"]+1; Application["ApplicationCount"]=applicationCount; } //若是session["sessionCount"]爲空,即沒有設置該名字的session if(Session["SessionCount"]==null) { Session["SessionCount"]=1; } else { sessionCount=(int)Session["SessionCount"]+1; Session["SessionCount"]=sessionCount; } Response.Write("當前頁面Application記錄訪問到了"+applicationCount+"次<br/>"); Response.Write("當前頁面Session記錄訪問到了"+sessionCount+"次<br/>"); %> </body> </html> 這是一個Dreamweaver中的.aspx的文件,運行可知結果。
轉自:https://www.cnblogs.com/wydchn/articles/4952209.html