1、客戶端和服務(wù)器之間的通信
HTTP協(xié)議規(guī)定,請(qǐng)求從客戶端發(fā)出,最后服務(wù)器端響應(yīng)該請(qǐng)求并返回。
下面是一個(gè)具體示例:
1> 客戶端發(fā)送請(qǐng)求(請(qǐng)求報(bào)文):
GET /index.htm HTTP/1.1
Host: harkr.jp
2> 服務(wù)器發(fā)送響應(yīng)(響應(yīng)報(bào)文):
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length 362
Content-Type: text/html
<html>
...
- 請(qǐng)求報(bào)文包括請(qǐng)求方法(如GET/POST等等)、請(qǐng)求URI(如/index.htm)、協(xié)議版本(如HTTP/1.1)、可選的請(qǐng)求首部字段和內(nèi)容實(shí)體。一個(gè)更具體的請(qǐng)求報(bào)文的構(gòu)成如下:
POST /form/entry HTTP/1.1
Host: hackr.jp
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 16
name=ueno&age=37
其中,POST是方法,/form/entry是請(qǐng)求URI,HTTP/1.1是協(xié)議版本號(hào),Host:.......Content-Length:16包含的內(nèi)容是各種請(qǐng)求首部字段,接著以空行分隔,之后的內(nèi)容name=....是內(nèi)容實(shí)體。
- 響應(yīng)報(bào)文基本由協(xié)議版本、狀態(tài)碼、用以解釋狀態(tài)碼的原因短語、可選的響應(yīng)首部字段以及實(shí)體主體構(gòu)成。下面是一個(gè)具體的響應(yīng)報(bào)文構(gòu)成示例:
HTTP/1.1 200 OK
Date: Tue, 10,Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html
<html>
...
其中,HTTP/1.1是協(xié)議版本,200是狀態(tài)碼,OK是解釋狀態(tài)碼的原因短語,Date:.....Content-Type: text/html是響應(yīng)首部字段,接著以一空行分隔,之后的內(nèi)容為資源實(shí)體的主體。
2、HTTP是無狀態(tài)協(xié)議
HTTP協(xié)議自身不對(duì)請(qǐng)求和響應(yīng)之間的通信狀態(tài)進(jìn)行保存。也就是說在HTTP這個(gè)級(jí)別,協(xié)議對(duì)于發(fā)送過的請(qǐng)求或響應(yīng)都不做持久化處理。
協(xié)議本身并不保留之前一切的請(qǐng)求或響應(yīng)報(bào)文的信息,這是為了更快速地處理大量事務(wù),確保協(xié)議的可伸縮性。
但是有時(shí)期望保持狀態(tài)功能(比如,用戶登錄到一家購物網(wǎng)站,即使他跳轉(zhuǎn)到該站的其他頁面同樣希望繼續(xù)保持其登錄狀態(tài)),于是引入了Cookie技術(shù)。
3、HTTP方法
- GET:獲取資源
GET方法用來請(qǐng)求訪問已被URI識(shí)別的資源。指定的資源經(jīng)服務(wù)器端解析后返回響應(yīng)內(nèi)容。若請(qǐng)求的資源是文本,則原樣返回;若是像CGI(通用網(wǎng)關(guān)接口)那樣的程序,則返回執(zhí)行后的輸出結(jié)果。
- POST:傳輸實(shí)體主體
POST方法用來傳輸實(shí)體的主體。
eg.
請(qǐng)求:
POST /submit.cgi HTTP/1.1
Host: www.hackr.jp
Content-Length: 1560(1560字節(jié)的數(shù)據(jù))
響應(yīng):返回submit.cgi接收數(shù)據(jù)的處理結(jié)果
- PUT:傳輸文件
PUT方法用來傳輸文件。就像FTP協(xié)議的文件上傳一樣,要求在請(qǐng)求報(bào)文的主體中包含文件內(nèi)容,然后保存到請(qǐng)求URI指定的位置。
但是,鑒于HTTP/1.1的PUT方法自身不帶驗(yàn)證機(jī)制,任何人都可以上傳文件,存在安全性問題,因此一般的Web網(wǎng)站不使用該方法。
eg.
請(qǐng)求:
PUT /example.html HTTP/1.1
Host: www.hackr.jp
Content-Type: text/html
Content-Length: 1560(1560字節(jié)的數(shù)據(jù))
響應(yīng):響應(yīng)返回狀態(tài)碼204 No Content(比如:該html已存在于服務(wù)器上。請(qǐng)求執(zhí)行成功,只是無數(shù)據(jù)返回)
- HEAD:獲得報(bào)文首部
HEAD方法和GET方法一樣,只是不返回報(bào)文主體部分。用于確認(rèn)URI的有效性及資源更新的日期時(shí)間等。
eg.
請(qǐng)求:
HEAD /index.html HTTP/1.1
Host: www.hackr.jp
響應(yīng):
返回index.html有關(guān)的響應(yīng)首部
- DELETE: 刪除文件
DELETE方法按請(qǐng)求URI刪除指定的資源。是與PUT相反的方法。
但是,同樣不帶驗(yàn)證機(jī)制,所以一般也不使用該方法。當(dāng)配合Web應(yīng)用程序的驗(yàn)證機(jī)制,或遵守REST標(biāo)準(zhǔn)時(shí)還是有可能會(huì)開放使用的。
eg.
請(qǐng)求:
DELETE /example.html HTTP/1.1
Host: www.hackr.jp
響應(yīng):響應(yīng)返回狀態(tài)碼204 No Content(比如:該html已經(jīng)從該服務(wù)器上刪除)
- OPTIONS: 詢問服務(wù)器支持的方法
OPTIONS方法用來查詢針對(duì)請(qǐng)求URI指定的資源支持的方法
eg.
請(qǐng)求:
OPTIONS * HTTP/1.1 // ->如果不是訪問特定資源而是對(duì)服務(wù)器本身發(fā)起請(qǐng)求,可以用一個(gè)*來代替請(qǐng)求URI
Host: www.hackr.jp
響應(yīng):
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS(返回服務(wù)器支持的方法)
- TRACE追蹤路徑
TRACE方法是讓W(xué)eb服務(wù)器將之前的請(qǐng)求通信環(huán)回給客戶端的方法。發(fā)送請(qǐng)求時(shí),在Max-Forwards首部字段中填入數(shù)值,每經(jīng)過一個(gè)服務(wù)器端將該數(shù)字減1,當(dāng)數(shù)值剛好減到0時(shí),就停止繼續(xù)傳輸,最后接收到請(qǐng)求的服務(wù)器端則返回狀態(tài)碼200 OK 的響應(yīng)。
客戶端通過TRACE方法可以查詢發(fā)送出去的請(qǐng)求是怎樣被加工修改/篡改的。這是因?yàn)?,?qǐng)求想要連接到源目標(biāo)服務(wù)器可能會(huì)通過代理服務(wù)器中轉(zhuǎn),TRACE方法就是用來確認(rèn)連接過程中發(fā)生的一系列操作。
但是,TRACE方法本來就不怎么常用,再加上它容易引發(fā)XST(跨站追蹤)攻擊,通常就更不會(huì)用到了。
- CONNECT: 要求用隧道協(xié)議連接代理
CONNECT方法要求在與代理服務(wù)器通信時(shí)建立隧道,實(shí)現(xiàn)用隧道協(xié)議進(jìn)行TCP通信。主要使用SSL(安全套接層)和TLS(傳輸層安全)協(xié)議把通信內(nèi)容加密后經(jīng)網(wǎng)絡(luò)隧道傳輸。
CONNECT方法的格式如下:
CONNECT 代理服務(wù)器名:端口號(hào) HTTP版本
eg.
請(qǐng)求:
CONNECT proxy.hackr.jp:8080 HTTP/1.1
Host; proxy.hackr.jp
響應(yīng):HTTP/1.1 200 OK(之后進(jìn)入網(wǎng)絡(luò)隧道)
4、持久連接
HTTP協(xié)議的初始版本中,每進(jìn)行一次HTTP通信就要斷開一次TCP連接。因此,每次的請(qǐng)求都會(huì)造成無謂的TCP連接建立和斷開,增加通信量的開銷。
所以,為了解決該問題,HTTP/1.1和一部分的HTTP/1.0想出了持久連接(HTTP Persistent Connections,也稱為HTTP keep-alive或HTTP connection reuse)的方法。
特點(diǎn)是,只要任意一端沒有明確提出斷開連接,則保持TCP連接狀態(tài)。旨在建立一次TCP連接后進(jìn)行多次請(qǐng)求和響應(yīng)的交互。
好處在于:減少了TCP連接的重復(fù)建立和斷開所造成的額外開銷,減輕了服務(wù)器端的負(fù)載。另外,減少開銷的那部分時(shí)間,使HTTP請(qǐng)求和響應(yīng)能夠更早地結(jié)束,這樣Web頁面的顯示速度就相應(yīng)提高了。
在HTTP/1.1中,所有的連接都是默認(rèn)持久連接。
- 管線化:持久連接是的多數(shù)請(qǐng)求以管線化方式發(fā)送。即同時(shí)并行發(fā)送多個(gè)請(qǐng)求,而不需要一個(gè)接一個(gè)地等待響應(yīng)了。
5、Cookie技術(shù)
Cookie技術(shù)通過在請(qǐng)求和響應(yīng)報(bào)文中寫入Cookie信息來控制客戶端的狀態(tài)。
Cookie會(huì)根據(jù)從服務(wù)器端發(fā)送的響應(yīng)報(bào)文內(nèi)的一個(gè)叫做Set-Cookie的首部字段信息,通知客戶端保存Cookie。當(dāng)下次客戶端再往該服務(wù)器發(fā)送請(qǐng)求時(shí),客戶端會(huì)自動(dòng)在請(qǐng)求報(bào)文中加入Cookie值后發(fā)送出去。服務(wù)器端發(fā)現(xiàn)客戶端發(fā)送過來的Cookie后,會(huì)檢查是從哪一個(gè)客戶端發(fā)來是連接請(qǐng)求,然后對(duì)比服務(wù)器上的記錄,最后得到之前的狀態(tài)信息。
Cookie交互示例:
1> 請(qǐng)求報(bào)文(沒有Cookie信息的狀態(tài))
GET /reader/ HTTP/1.1
Host: hackr.jp //首部字段內(nèi)沒有Cookie的相關(guān)信息
2> 響應(yīng)報(bào)文(服務(wù)器端生成Cookie信息)
HTTP/1.1 200 OK
Date: Tue, 10,Jul 2012 06:50:15 GMT
Server: Apache
<Set-Cookie: sid=1342077140226724; path=/; expires=Wed,=>10-Oct-12 06:50:15 GMT>
Content-Type: text/plain; charset=UTF-8;
3> 請(qǐng)求報(bào)文(自動(dòng)發(fā)送保存著的Cookie信息)
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724
##6、多部分對(duì)象集合及范圍請(qǐng)求
- 多部分對(duì)象集合
發(fā)送的一份報(bào)文主體內(nèi)可能含有多種類型實(shí)體,比如:文本、圖片、視頻等。
多部分對(duì)象集合包含的對(duì)象有:`multipart/form-data`(在Web表單文件上傳時(shí)使用)和`multipart/byterangees`(狀態(tài)碼206(Partial Content,部分內(nèi)容)響應(yīng)報(bào)文包含了多個(gè)范圍的內(nèi)容時(shí)使用)
- 范圍請(qǐng)求
從之前下載中斷處恢復(fù)下載需要指定下載的實(shí)體范圍,像這樣指定范圍發(fā)送請(qǐng)求叫做范圍請(qǐng)求。例如,對(duì)一份10000字節(jié)大小的資源,如果使用范圍請(qǐng)求,可以只請(qǐng)求5001-10000字節(jié)內(nèi)的資源。只想范圍請(qǐng)求時(shí),會(huì)用到首部字段Range來指定資源的byte范圍。指定形式如下:
Range: bytes=5001-10000 //5001-10000字節(jié)
Range: bytes=5001- //從5001字節(jié)之后全部的
Range: bytes=-3000, 5000-7000 //從一開始到3000字節(jié)和5000-7000字節(jié)的多重范圍
##7、內(nèi)容協(xié)商
內(nèi)容協(xié)商機(jī)制是指客戶端和服務(wù)器就響應(yīng)的資源內(nèi)容進(jìn)行交涉,然后提供給客戶端最為適合的資源。內(nèi)容協(xié)商會(huì)以響應(yīng)資源的語言、字符集、編碼方式等作為判斷的基準(zhǔn)。
有3中類型:
- 服務(wù)器驅(qū)動(dòng)協(xié)商
- 客戶端驅(qū)動(dòng)協(xié)商
- 透明協(xié)商
##8、HTTP狀態(tài)碼

經(jīng)常使用的狀態(tài)碼有14種:
- 200 OK
表示從客戶端發(fā)來的請(qǐng)求在服務(wù)器端被正常處理了。
- 204 No Content
代表服務(wù)器接收的請(qǐng)求已經(jīng)處理成功,但在返回的響應(yīng)報(bào)文中不含實(shí)體的主體部分。另外,也不允許返回任何實(shí)體的主體。
- 206 Partial Content
表示客戶端進(jìn)行了范圍請(qǐng)求,而服務(wù)器成功執(zhí)行了這部分的GET請(qǐng)求。響應(yīng)報(bào)文中包含由Content-Range指定范圍的實(shí)體內(nèi)容。
- 301 Moved Permanently
永久性重定向。表示請(qǐng)求的資源已被分配了新的URI,以后使用資源現(xiàn)在所指的URI。
- 302 Found
臨時(shí)性重定向。表示請(qǐng)求的資源已被分配了新的URI(臨時(shí)性質(zhì)的),希望用戶(本次)使用新的URI訪問。
- 303 See Other
表示請(qǐng)求對(duì)應(yīng)的資源存在著另一個(gè)URI,(明確表示)應(yīng)使用GET方法定向獲取請(qǐng)求的資源。
- 304 Not Modified
表示客戶端發(fā)送*附帶條件的請(qǐng)求*(附帶條件的請(qǐng)求是指GET方法的請(qǐng)求報(bào)文中包含If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since中任一首部)時(shí),服務(wù)器端允許請(qǐng)求訪問資源,但因發(fā)生請(qǐng)求未滿足條件的情況后,直接返回304 Not Modified(服務(wù)器資源未改變,可直接使用客戶端未過期的緩存)。304狀態(tài)碼返回時(shí),不包含任何響應(yīng)的主體部分。304和重定向沒有關(guān)系。
- 307 Temporary Redirect
臨時(shí)重定向。與302 Found有著相同的含義。
- 400 Bad Request
該狀態(tài)碼表示請(qǐng)求報(bào)文中存在語法錯(cuò)誤。當(dāng)錯(cuò)誤發(fā)生時(shí),需修改請(qǐng)求的內(nèi)容后再次發(fā)送請(qǐng)求。另外,瀏覽器會(huì)像200 OK一樣對(duì)待該狀態(tài)碼。
- 401 Unauthorized
表示發(fā)送的請(qǐng)求需要有通過HTTP認(rèn)證(BASIC 認(rèn)證、DIGEST 認(rèn)證)的認(rèn)證信息。另外若之前已進(jìn)行過1次請(qǐng)求,則表示用戶認(rèn)證失敗。
當(dāng)瀏覽器初次接收到401響應(yīng),會(huì)彈出認(rèn)證用的對(duì)話窗口。
- 403 Forbidden
表明對(duì)請(qǐng)求資源的訪問被服務(wù)器拒絕了。比如未獲得文件系統(tǒng)的訪問授權(quán),訪問權(quán)限出現(xiàn)某些問題(從未授權(quán)的發(fā)送源IP地址試圖訪問)等情況都可能發(fā)生403。
- 404 Not Found
表明服務(wù)器上無法找到請(qǐng)求的資源。除此之外,也可以在服務(wù)器端拒絕請(qǐng)求且不想說明理由時(shí)使用。
- 500 Internal Server Error
表明服務(wù)器端在執(zhí)行請(qǐng)求時(shí)發(fā)生了錯(cuò)誤。也有可能是Web應(yīng)用存在的BUG或某些臨時(shí)的故障。
- 503 Service Unavailable
表明服務(wù)器暫時(shí)處于超負(fù)載或正在進(jìn)行停機(jī)維護(hù),現(xiàn)在無法處理請(qǐng)求。
**狀態(tài)碼和狀況的不一致**:不少返回的狀態(tài)碼響應(yīng)是錯(cuò)誤的。但是用戶可能察覺不到。比如Web應(yīng)用程序內(nèi)部發(fā)生錯(cuò)誤,狀態(tài)碼依然返回200 OK,這種情況也經(jīng)常遇到。