HTTP 協議解析

HTTP協議簡介

超文本傳輸協議(英文:HyperText Transfer Protocol,縮寫:HTTP)是互聯網上應用最爲廣泛的一種網絡協議。設計HTTP最初的目的是爲了

提供一種發佈和接收HTML頁面的方法。通過HTTP或者HTTPS協議請求的資源由統一資源標識符(Uniform Resource Identifiers,URI)來標識。

HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型。HTTP是基於TCP/IP的無連接,無狀態的協議(每一個HTTP報文

不依賴於其前面的報文狀態)。HTTP假定其下層協議提供可靠的傳輸。因此也就是其在TCP/IP協議族使用TCP作爲其傳輸層。

如圖爲我們常說的tcp/ip協議棧。Internet四層網絡模型(也叫TCP/IP四層模型)包括數據鏈路層(網絡接口)、網絡層、傳輸層和應用層。

                                   

 HTTP協議的主要特點可概括如下:

  簡單:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的不同類型。
              由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。

 靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。

 請求-響應模式:客戶端每次向服務器發起一個請求時都建立一個連接, 服務器處理完客戶的請求即斷開連接。

 無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能

                導致每次連接傳送的數據量增大。

HTTP工作流程

HTTP,是符合C/S模型的,總是Client端來發起請求。

1、客戶機(瀏覽器)主動向服務器(web   server)發出連接請求。 

2、服務器接受連接請求並建立起連接。 (1,2步即我們所熟知的TCP三次握手)

3、客戶機通過此連接向服務器發出GET等http命令,(“HTTP請求報文”)。

4、服務器接到命令並根據命令向客戶機傳送相應的數據,(“HTTP響應報文”)。

5、客戶機接收從服務器送過來的數據。

6、服務器發送完數據後,主動關閉此次連接。 (”TCP四次分手“)。

概況起來就是 客戶/服務器傳輸過程可分爲四個基本步驟:

  1) 瀏覽器與服務器建立連接; (TCP三次握手)

  2) 瀏覽器向服務器請求文檔;

  3) 服務器響應瀏覽器請求;

  4) 斷開連接。(”TCP四次分手“)

HTTP協議的URL,URI介紹

HTTP協議中的URL(URL是一種特殊類型的URI(Uniform Resource Identifier),包含了用於查找某個資源的足夠的信息)

主要是用於定位服務器端資源的位置。我們來看下它的語法定義:

http://host[:port][path]

其中:

http:// 表示我們要使用HTTP協議;

host 表示一個可用的域名或IP地址;

port 爲可選,表示要請求的端口號,缺省情況下爲80

path 爲可選,表示要請求的資源所在的路徑(也叫URI),缺省情況下爲/ ,如果URL中沒有給出path,那麼當它作爲請求URI時,

必須以“/”的形式給出,比如瀏覽器中輸入: www.abc.edu.cn 則瀏覽器自動換成 www.abc.edu.cn/ 。

HTTP協議結構

HTTP協議格式比較簡單,格式如下:

                                            

由上圖也可以看出來  HTTP 有兩類報文:

請求報文——從客戶向服務器發送請求報文。

響應報文——從服務器到客戶的回答。

請求報文

請求報文 報文格式如下:

                                                    

空白行用CR LF對錶示。CR LF對是回車(Carriage Return,CR)和換行(Line Feed,LF)字符的ASCII碼,它表示報頭組件的結束。

爲了深入理解HTTP 協議請求報文,下面直接來一個例子:

GET /t5/style/css/module/base/home_frame.css?version=cc73de6cd25d6dbf HTTP/1.1
/* 第一行叫做請求行(request),其他的各行都叫做頭部行(header)請求行包括三個字段:
方法字段、URI字段、HTTP版本字段 這個例子的請求行,是要做這樣一件事:用HTTP協議
1.1版本,使用GET方法,向服務端申請/t5/style/css/module/base/home_frame.css?version=cc73de6cd25d6dbf資源 */
/* 下面都屬於頭部行 */
Host: img.t.sinajs.cn
/* Host用來指定要請求的服務器端主機爲img.t.sinajs.cn,呵呵是新浪的*/
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0
 /* User-agent域則是用來指定當前這個請求報文是由誰產生的,通常來說,一般這裏設置的是用戶所使用的瀏覽器類型。*/
Accept: text/css,*/*;q=0.1
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
 /* Accept-language域,客戶端所能識別的語言 如果沒有 則 採取默認語言 */
Accept-Encoding: gzip, deflate
/*客戶端所能識別的編碼壓縮格式 gzip*/
Referer: http://weibo.com/840450770/home=5&page=2&pre_page=1&end_id=3664048949921640&end_msign=-1
Connection: keep-alive

/* 這裏有一個空行,而且是必須有這個空行。這是HTTP協議的硬性規定。 */
請求報文段就是下面這樣,細細琢磨吧。

GET /t5/style/css/module/base/home_frame.css?version=cc73de6cd25d6dbf HTTP/1.1
Host: img.t.sinajs.cn
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/css,*/*;q=0.1
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://weibo.com/840450770/home?wvr=5&page=2&pre_page=1&end_id=3664048949921640&end_msign=-1
Connection: keep-alive

HTTP 請求方法概述:

                         

客戶程序向服務器發送的請求可以有不同的類型,這樣服務器可以根據不同的請求類型進行不同的處理。

響應報文

響應報文格式如下:

                                      

  一般情況下,服務器接收並處理客戶端發過來的請求後會返回一個HTTP的響應消息。HTTP的響應消息也是由三個部分組成,

分別是:狀態行、消息報頭、響應正文。

應用舉例:

 /* 第一行是狀態行,包括三個字段:版本字段、狀態碼字段、原因短語字段 */
HTTP/1.1 200 OK
/* 本例中,HTTP協議的響應報文想表達的意思是服務器使用的是HTTP協議1.1版本,
   而且找到了客戶端所要的資源,且會將響應報文發給客戶端,整個過程都很正常 */
Expires: Wed, 22 Jan 2014 02:51:09 GMT
/*給出響應過期的日期和時間。爲了讓代理服務器或瀏覽器在一段時間以後更新緩存中
(再次訪問曾訪問過的頁面時,直接從緩存中加載,縮短響應時間和降低服務器負載)的頁面,
我們可以使用Expires指定頁面過期的時間)*/
Date: Tue, 07 Jan 2014 02:51:09 GMT
/* 這裏記錄了這個響應報文被髮送出去的時間點 */
Server: nginx/1.4.2
/* Server域表明這個響應報文是nginx服務器發出的,且nginx的版本是1.4.2 */
Content-Type: text/css
/* 指出所包含的數據是txt/css文本內容 */
Last-Modified: Mon, 06 Jan 2014 07:50:31 GMT
/* 用於記錄本響應報文中所存的數據的最後修改時間 */
Transfer-Encoding: chunked
/*服務端向客戶端傳輸數據所採用的傳輸模式(僅在HTTP1.1中出現)*/
Cache-Control: max-age=1296000
/*服務端要求中間代理及客戶端如何緩存自己響應的數據*/
Content-Encoding: gzip
/*用於記錄文檔的壓縮方法 gzip*/
Age: 1
X-Via: 1.1 whjyw137:3 (Cdn Cache Server V2.0)
Connection: keep-alive
/* 服務器端會保持住這個連接*/

 /* 看這裏,還得看這裏,和請求報文類似,這裏也有一個空行 */
  (實際數據 …………)
響應報文,原報文如下:

HTTP/1.1 200 OK
Expires: Wed, 22 Jan 2014 02:51:09 GMT
Date: Tue, 07 Jan 2014 02:51:09 GMT
Server: nginx/1.4.2
Content-Type: text/css
Last-Modified: Mon, 06 Jan 2014 07:50:31 GMT
Transfer-Encoding: chunked
Cache-Control: max-age=1296000
Content-Encoding: gzip
Age: 1
X-Via: 1.1 whjyw137:3 (Cdn Cache Server V2.0)
Connection: keep-alive

835a
?

HTTP狀態碼

狀態碼都是三位數字 ,第一位表示狀態類別,共分五種,如下圖:

                                       

其實常用的狀態碼並不多,我們把常見的列舉在此:
    200 OK:客戶端請求成功了,客戶端要的東西就在響應報文裏了;

    301 Moved Permanently:客戶端啊,你要請求的資源已經永久的搬家了,我把他的新地址放到了Location頭部域中了;

    302 Moved Temporarily:客戶端啊,你要請求的資源臨時有事去別的地方了,我把他的位置放到了Location頭部域中了,

            你可以先去那裏找他,不過他應該是會回到他自己的家的;

    304 Not Modified:客戶端啊,你要請求的資源自從上次你請求之後,就再也沒有改動過,我想你是應該早就有這個資源了,

             所以在響應報文的數據部分我也沒有再放這個資源。

    400 Bad Request:客戶端發來的請求報文裏有語法錯誤,服務器端實在看不懂了;

    401 Unauthorized:客戶端發來的請求不是合法來源的請求,也就是這個客戶端是沒有被授權的;

    403 Forbidden:服務器端順利收到了客戶端的請求,但是因爲某些理由,服務器端拒絕爲他提供服務;

    404 Not Found:客戶端要請求的資源不存在,八成是資源地址寫錯了;

    500 Internal Server Error:很遺憾,服務器不能給你提供服務了,服務器內部出現了不可預知的問題了;

    502 Bad Gateway:客戶端你好,我是請求報文的代理服務器,持有資源的那個服務器在給我發送資源時出問題了;

    503 Server Unavailable:服務器現在可能是太忙了,暫時不能給你這個客戶端提供服務了,或許稍後會恢復。

HTTP常見問題

HTTP協議是無狀態的和Connection: keep-alive的區別

  無狀態是指協議對於事務處理沒有記憶能力,服務器不知道客戶端是什麼狀態。從另一方面講,打開一個服務器上的網頁和你之前打開這個服務器上的

  網頁之間沒有任何聯繫。HTTP是一個無狀態的面向連接的協議,無狀態不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協議(無連接)。

 從HTTP/1.1起,默認都開啓了Keep-Alive,保持連接特性,簡單地說,當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP連接不會關閉,

 如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件

(如Apache)中設定這個時間。

更多知識請參考 相關RFC文檔。

參考資料:

http://www.rfc-editor.org/info/rfc2616

http://blog.csdn.net/daniel_ustc/article/details/12043469

http://my.oschina.net/johnsony/blog/113090

http://my.oschina.net/aiguozhe/blog/41313

http://roclinux.cn/?p=3450#more-3450





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章