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