1 HTTP協議的概念和歷史
1.1 什麼是HTTP協議
HTTP協議是超文本傳送協議(HyperText Transfer Protocol)的縮寫,它是萬維網(World Wide Web,www,也簡稱爲Web)的基礎。HTTP協議設計之初就是爲了實現Web的想法。HTTP協議位於TCP/IP協議棧的應用層。
我們在瀏覽器的地址欄裏輸入的網站地址叫做URL(UniformResourceLocator,統一資源定位符)。就像每家每戶都有一個門牌地址一樣,每個網頁也都有一個Internet地址。當你在瀏覽器的地址框中輸入一個URL或是單擊一個超級鏈接時,URL就確定了要瀏覽的地址。瀏覽器通過超文本傳輸協議(HTTP),將Web服務器上站點的網頁代碼提取出來,並呈現出客戶端需要的網頁。
HTTP協議使用的默認端口是80,同時也支持自定義端口。
1.2 HTTP協議的歷史
HTTP協議到現在爲止總共經歷了3個版本的演化,第一個HTTP協議誕生於1989年3月。當時Berners-Lee向 CERN(Conseil Europeen pour la Recherche Nucleaire,歐洲核能研究所)提交了一篇名爲《信息管理的一個提議》的文章。文章中提出了www網絡的構想,不過僅僅在很多方面都只關注了概念,而沒涉及到細節。
第一個HTTP協議的版本是HTTP 0.9,它的組成極其簡單,因爲它只允許客戶端發送GET這一種請求,它不包含協議頭,每個請求只有一句話,例如:
GET /index.html
由於沒有協議頭,造成了HTTP 0.9協議只支持一種內容,即純文本。不過網頁仍然支持用HTML語言格式化,同時無法插入圖片。所以HTTP 0.9能夠支持的應用實在太有限了。一次HTTP 0.9的傳輸首先要建立一個由客戶端到Web服務器的TCP連接,由客戶端發起一個請求,然後由Web服務器返回頁面內容,然後連接會關閉。如果請求的頁面不存在,也不會返回任何錯誤碼。
HTTP 0.9的缺點是顯著的,但至少實現了第一代的Web。
HTTP協議的第二個版本是HTTP 1.0,直到HTTP 1.0成爲最重要的面向事務的應用層協議。該協議對每一次請求/響應,同樣是建立並關閉一次連接。其特點是簡單、易於管理,所以它符合了大家的需要,得到了廣泛的應用。
並且HTTP 1.0最顯著的變化之一是開始支持客戶端通過POST方法向Web服務器提交數據。從此客戶端與Web服務器之間不再只能單向地獲取數據,而可以實現交互,因此CGI(Common Gate Interface,通用網關接口)開始流行起來,Web上開始出現留言板、論壇等豐富的應用。
HTTP 1.0還有個顯著的變化是通過HTTP協議頭可以支持各種媒體類型。從此Web上不再僅僅是純文本的頁面,比如圖像通過<img>的HTML標記開始出現。
除了以上幾個新特性,HTTP 1.0支持長連接(但默認還是使用短連接),緩存機制,以及身份認證。
雖說HTTP協議的設計是向前兼容的,但目前很多瀏覽器和Web服務器都強制要求HTTP協議版本至少是1.0。
HTTP協議的第三個版本是HTTP 1.1,它就是目前使用最廣泛的協議版本。這個版本的HTTP協議已經穩定了,跟HTTP 1.0相比,它新增了很多引人注目的新特性,比如Host協議頭,一個HTTP請求的頭中可以包含一句例如:
Host: vimer.cn
從此一個Web服務器可以支持掛載多個域名了,無需每個域名都使用獨立IP,每個網站可以使用虛擬主機。
另一個HTTP 1.1的新特性是支持部分內容請求/響應,這意味着當客戶端請求的數據量很大時,可以分多次發起請求,每次請求只要求獲取整塊數據的一部分。Web服務器也可以分多次響應,每次只返回整塊數據的一部分。這使得流媒體得以實現。
從HTTP 1.1開始,客戶端默認與Web 服務器建立長連接,這種連接適合Web上數據量較大的豐富應用,使得資源消耗更少。
QzHTTP就是一個支持HTTP 1.1協議的Web Server。
2.HTTP協議內容介紹
2.1 URI
HTTP協議通過URI(Uniform Resource Identifiers,統一資源定位符)來訪問資源。根據RFC 1808的官方定義,一個完整URI的組成如下:
http://myname:[email protected]:80/mydir/myfile.html?myvar=myvalue#myfrag
URI字段
表 2.1
URI部分 |
意義 |
http |
協議名稱 |
myname |
用戶名(可選) |
mypass |
密碼(可選) |
主機網絡地址 |
|
80 |
端口號(可選) |
/mydir/myfile.html |
資源路徑 |
myvar=myvalue |
查詢字符串(可選) |
myfrag |
錨點(可選) |
可見協議名稱用“://”結束,用戶名和密碼以“:”分隔,以“@”結束,端口號與主機網絡地址以“:”分隔,資源路徑與查詢字符串以“?”分隔,錨點以#開頭。
並且,只有協議名稱、主機網絡地址和資源路徑是必須包含在URI裏的。
一個更常見的例子如下:
在這裏面,http是協議,www.vimer.cn是主機網絡地址,注意末尾的/就是資源路徑,這是必須的。當我們平時使用Web瀏覽器訪問時,只需要輸入www.vimer.cn就可以訪問,這是由於Web瀏覽器替我們自動補齊了前面的http://和最後的/,Web瀏覽器發起請求時使用的URI還是完整的,Web瀏覽器並不強制用戶輸入格式規範的URI。
2.2 HTTP請求與響應
HTTP協議的交互主要由請求和響應組成,請求是指客戶端發起向Web服務器請求資源的消息,而響應是Web服務器根據客戶端的請求回送給客戶端的資源消息。
發出的請求信息(Request Message)包括以下幾部分:
l 請求行,例如GET /images/logo.gif HTTP/1.1,表示從/images 目錄下請求logo.gif 這個文件。
l (請求)頭,例如Accept-Language: en
l 空行
l 可選的消息體
請求行和標題必須以<CR><LF> 作爲結尾(也就是,回車然後換行)。空行內必須只有<CR><LF>而無其他空格。在HTTP/1.1 協議中,所有的請求頭,除Host外,都是可選的。
請求方法(Request Method)
HTTP/1.1協議中共定義了八種方法(有時也叫“動作”)來表明Request-URI指定的資源的不同操作方式:
l OPTIONS
返回服務器針對特定資源所支持的HTTP請求方法。也可以利用向Web服務器發送’*’的請求來測試服務器的功能性。
l HEAD
向服務器索要與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應消息頭中的元信息。
l GET
向特定的資源發出請求。注意:GET方法不應當被用於產生“副作用”的操作中,例如在Web 應用程序中。其中一個原因是GET可能會被網絡蜘蛛等隨意訪問。
l POST
向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
l PUT
向指定資源位置上傳其最新內容。
l DELETE
刪除指定資源。
l TRACE
回顯服務器收到的請求。
l CONNECT
HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。
方法名稱是區分大小寫的。當某個請求所針對的資源不支持對應的請求方法的時候,服務器應當返回狀態碼405(Method Not Allowed);當服務器不認識或者不支持對應的請求方法的時候,應當返回狀態碼501(Not Implemented)。
HTTP服務器至少應該實現GET和HEAD方法,其他方法都是可選的,可選方法中還有一個重要的方法是POST。當然,所有的方法支持的實現都應當符合下述的方法各自的語義定義。此外,除了上述方法,特定的HTTP服務器還能夠擴展自定義的方法。
一個GET請求的示例如圖2.3所示:
圖2.3 HTTP請求
GET 代表方法名,後面的/代表資源路徑,HTTP/1.1表示協議版本。下面都是協議頭部分,常見的頭字段如表2.2所示。
HTTP協議頭字段
表2.2
頭字段 |
定義 |
Accept |
客戶端可以處理的媒體類型(MIME-Type),按優先級排序;在一個以逗號爲分隔的列表中,可以定義多種類型和使用通配符 |
Accept-Language |
客戶端支持的自然語言列表 |
Accept-Encoding |
客戶端支持的編碼列表 |
User-Agent |
客戶端環境類型 |
Host |
服務器端的主機地址 |
Connection |
連接類型,默認爲Keep-Alive |
HTTP協議是Web內容的容器。一個示例HTTP響應如圖2.4所示:
圖2.4 HTTP響應
每個響應由HTTP協議頭和Web內容構成。Web服務器收到一個請求,就會立刻解釋請求中所用到的方法,並開始處理應答。服務器的響應消息也包含頭字段形式的協議頭。響應的格式在RFC2616中定義如下:
Status-Line*
(( general-header)| response-header | entity-header)CRLF)
CRLF
[ message-body ]
響應消息的第一行是狀態行(Stauts-Line),由協議版本以及數字狀態碼和相關的文本短語組成,各部分間用空格符隔開,除了最後的回車或換行外,中間不允許有回車換行。
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
狀態碼是試圖理解和滿足請求的三位數字的整數碼, 原因短語(Reason-Phrase)是爲了給出的關於狀態碼的文本描述。狀態碼用於控制條件,而原因短語(Reason-Phrase)是讓用戶便於閱讀。客戶端不需要檢查和顯示原因短語。
狀態碼的第一位數字定義響應類型。後兩位數字沒有任何分類角色。第一位數字有五種值,如表2.3所示。
HTTP響應狀態碼
表 2.3
狀態碼 |
定義 |
1xx 報告 |
接收到請求,繼續進程 |
2xx 成功 |
步驟成功接收,被理解,並被接受 |
3xx 重定向 |
爲了完成請求,必須採取進一步措施 |
4xx 客戶端出錯 |
請求包括錯的順序或不能完成 |
5xx 服務器出錯 |
服務器無法完成顯然有效的請求 |
下面列舉了爲HTTP/1.1定義的狀態碼值,和對應的原因短語(Reason-Phrase)的例子。
l 客戶端錯誤
“100″ : Continue 繼續
“101″ : witching Protocols 交換協議
l 成功
“200″ : OK
“201″ : Created 已創建
“202″ : Accepted 接收
“203″ : Non-Authoritative Information 非認證信息
“204″ : No Content 無內容
“205″ : Reset Content 重置內容
“206″ : Partial Content 部分內容
l 重定向
“300″ : Multiple Choices 多路選擇
“301″ : Moved Permanently 永久轉移
“302″ : Found 暫時轉移
“303″ : See Other 參見其它
“304″ : Not Modified 未修改
“305″ : Use Proxy 使用代理
“307″ : Temporary Redirect
l 客戶方錯誤
“400″ : Bad Request 錯誤請求
“401″ : Unauthorized 未認證
“402″ : Payment Required 需要付費
“403″ : Forbidden 禁止
“404″ : Not Found 未找到
“405″ : Method Not Allowed 方法不允許
“406″ : Not Acceptable 不接受
“407″ : Proxy Authentication Required 需要代理認證
“408″ : Request Time-out 請求超時
“409″ : Conflict 衝突
“410″ : Gone 失敗
“411″ : Length Required 需要長度
“412″ : Precondition Failed 條件失敗
“413″ : Request Entity Too Large 請求實體太大
“414″ : Request-URI Too Large 請求URI太長
“415″ : Unsupported Media Type 不支持媒體類型
“416″ : Requested range not satisfiable
“417″ : Expectation Failed
l 服務器錯誤
“500″ : Internal Server Error 服務器內部錯誤
“501″ : Not Implemented 未實現
“502″ : Bad Gateway 網關失敗
“503″ : Service Unavailable
“504″ : Gateway Time-out 網關超時
“505″ : HTTP Version not supported HTTP版本不支持
HTTP狀態碼是可擴展的。HTTP應用程序不需要理解所有已註冊狀態碼的含義,儘管那樣的理解顯而易見是很合算的。但是,應用程序必須瞭解由第一位數字指定的狀態碼的類型,任何未被識別的響應應被看作是該類型的x00狀態,有一個例外就是未被識別的響應不能緩存。例如,如果客戶端收到一個未被識別的狀態碼431,則可以安全的假定請求有錯,並且它會對待此響應就像它接收了一個狀態碼是400的響應。在這種情況下,用戶代理(user agent)應當把實體和響應一起提交給用戶,因爲實體很可能包括人可讀的關於解釋不正常狀態的信息。報文最後是實體信息,即客戶請求得到的HTTP服務器上的資源內容。
點擊這裏下載原版pdf