一、概念
超文本傳輸協(xié)議(英文:HyperText Transfer Protocol,縮寫:HTTP)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議祈匙。設(shè)計(jì)HTTP最初的目的是為了提供一種發(fā)布和接收HTML頁(yè)面的方法魏保。通過(guò)HTTP或者HTTPS協(xié)議請(qǐng)求的資源由統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifiers,URI)來(lái)標(biāo)識(shí)漂坏。HTTP構(gòu)建于TCP/IP協(xié)議之上景埃,默認(rèn)端口是80媒至;HTTP是無(wú)連接無(wú)狀態(tài)的。
HTTP 協(xié)議是基于請(qǐng)求與響應(yīng)的:
二谷徙、HTTP報(bào)文
1.請(qǐng)求方法
HTTP1.1目前支持7種請(qǐng)求方法拒啰。
GET
GET方法是默認(rèn)的HTTP請(qǐng)求方法,日常用GET方法來(lái)提交表單數(shù)據(jù)完慧,然而用GET方法提交的表單數(shù)據(jù)只經(jīng)過(guò)了簡(jiǎn)單的編碼谋旦,同時(shí)它將作為URL的一部分向WEB服務(wù)器發(fā)送。因此屈尼,如果使用GET方法來(lái)提交表單數(shù)據(jù)就存在安全隱患册着。
如:https://www.google.co.jp/search?q=http協(xié)議&oq=http協(xié)議POST
主要向服務(wù)器提交數(shù)據(jù),尤其是大批量數(shù)據(jù)脾歧。POST方法克服了GET方法的一些缺點(diǎn)甲捏。通過(guò)POST提交數(shù)據(jù)時(shí),數(shù)據(jù)不是作為URL請(qǐng)求的一部分而是作為標(biāo)準(zhǔn)數(shù)據(jù)傳送給服務(wù)器鞭执,克服了GET中信息無(wú)法保密和數(shù)據(jù)量太小的缺點(diǎn)司顿。HEAD
請(qǐng)求獲取有Request-URI所標(biāo)識(shí)的資源的響應(yīng)消息報(bào)頭。OPTIONS
請(qǐng)求查詢服務(wù)器的性能兄纺,或查詢與資源相關(guān)的選項(xiàng)和需求大溜。PUT
請(qǐng)求服務(wù)器存儲(chǔ)一個(gè)資源,并用Request-URI作為標(biāo)識(shí)估脆。DELETE
請(qǐng)求服務(wù)器刪除由Request-URI標(biāo)識(shí)的資源猎提。TRACE
請(qǐng)求服務(wù)器回送收到的請(qǐng)求信息,主要用于測(cè)試或診斷旁蔼。
2.請(qǐng)求報(bào)文
請(qǐng)求報(bào)文由三個(gè)部分組成:
- 請(qǐng)求行
請(qǐng)求行由請(qǐng)求方法锨苏、URL和HTTP協(xié)議版本組成,用空格分隔棺聊。如:GET /index.html HTTP/1.1 -
請(qǐng)求頭
請(qǐng)求頭部由關(guān)鍵字/值對(duì)組成伞租,每行一對(duì),關(guān)鍵字和值用英文冒號(hào)“:”分隔限佩。請(qǐng)求頭部通知服務(wù)器有關(guān)于客戶端請(qǐng)求的信息葵诈。例如:
User-Agent:產(chǎn)生請(qǐng)求的瀏覽器類型。
Accept:客戶端可識(shí)別的內(nèi)容類型列表祟同。
Host:請(qǐng)求的主機(jī)名作喘,允許多個(gè)域名同處一個(gè)IP地址,即虛擬主機(jī)晕城。
- 請(qǐng)求正文
請(qǐng)求頭和請(qǐng)求正文之間是一個(gè)空行泞坦,這個(gè)行非常重要,它表示請(qǐng)求頭已經(jīng)結(jié)束砖顷,接下來(lái)的是請(qǐng)求正文贰锁。請(qǐng)求正文中可以包含客戶提交的查詢字符串信息赃梧。
下面是一個(gè)典型的請(qǐng)求報(bào)文:
GET /sample.jsp HTTP/1.1
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=jinqiao&password=1234
3.響應(yīng)報(bào)文
響應(yīng)報(bào)文也由三部分組成:
- 狀態(tài)行
狀態(tài)行由協(xié)議版本、數(shù)字形式的狀態(tài)代碼豌熄、及相應(yīng)的狀態(tài)描述授嘀,各元素之間以空格分隔。如: HTTP/1.1 200 OK
狀態(tài)碼由三個(gè)數(shù)字組成锣险,第一個(gè)數(shù)字定義了響應(yīng)的類別:
1xx:指示信息--表示請(qǐng)求已接收蹄皱,繼續(xù)處理。
2xx:成功--表示請(qǐng)求已被成功接收芯肤、理解夯接、接受。
3xx:重定向--要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作纷妆。
4xx:客戶端錯(cuò)誤--請(qǐng)求有語(yǔ)法錯(cuò)誤或請(qǐng)求無(wú)法實(shí)現(xiàn)。
5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求晴弃。
常見的狀態(tài)碼如下:
200 OK 客戶端請(qǐng)求成功
301 Moved Permanently 請(qǐng)求永久重定向
302 Moved Temporarily 請(qǐng)求臨時(shí)重定向
304 Not Modified 文件未修改掩幢,可以直接使用緩存的文件。
400 Bad Request 由于客戶端請(qǐng)求有語(yǔ)法錯(cuò)誤上鞠,不能被服務(wù)器所理解际邻。
401 Unauthorized 請(qǐng)求未經(jīng)授權(quán)。這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用
403 Forbidden 服務(wù)器收到請(qǐng)求芍阎,但是拒絕提供服務(wù)世曾。服務(wù)器通常會(huì)在響應(yīng)正文中給出不提供服務(wù)的原因
404 Not Found 請(qǐng)求的資源不存在,例如谴咸,輸入了錯(cuò)誤的URL
500 Internal Server Error 服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤轮听,導(dǎo)致無(wú)法完成客戶端的請(qǐng)求。
503 Service Unavailable 服務(wù)器當(dāng)前不能夠處理客戶端的請(qǐng)求岭佳,在一段時(shí)間之后血巍,服務(wù)器可能會(huì)恢復(fù)正常。
-
響應(yīng)頭
與請(qǐng)求頭部類似珊随,為響應(yīng)報(bào)文添加了一些附加信息
常見響應(yīng)頭部如下:
- 響應(yīng)正文
用于存放需要返回給客戶端的數(shù)據(jù)信息述寡。
一個(gè)典型的響應(yīng)報(bào)文如下:
HTTP/1.1 200 OK 狀態(tài)行
Date: Sun, 17 Mar 2013 08:12:54 GMT 響應(yīng)頭部
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
空行
<html> 響應(yīng)數(shù)據(jù)
<head>
<title>HTTP響應(yīng)示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
三、無(wú)連接和無(wú)狀態(tài)
HTTP有兩個(gè)重要的特點(diǎn)就是無(wú)連接和無(wú)狀態(tài)叶洞。怎么理解呢鲫凶?
1.無(wú)連接
它的含義是限制每次連接只處理一個(gè)請(qǐng)求。服務(wù)器處理完客戶的請(qǐng)求衩辟,并收到客戶的應(yīng)答后螟炫,即斷開連接。采用這種方式可以節(jié)省傳輸時(shí)間艺晴。
然而隨著互聯(lián)網(wǎng)的發(fā)展不恭,一臺(tái)服務(wù)器同一時(shí)間處理的請(qǐng)求越來(lái)越多叶雹,如果依然采用原來(lái)的方式,將會(huì)在建立和斷開連接上花費(fèi)大部分時(shí)間换吧。
HTTP/1.0:持久連接被提出來(lái)折晦;即當(dāng)一個(gè)TCP連接服務(wù)器多次請(qǐng)求:客戶端會(huì)在請(qǐng)求Header中攜帶Connection:Keep-Alive;向服務(wù)器請(qǐng)求持久連接,如果服務(wù)端允許就會(huì)在響應(yīng)報(bào)文中加上相同的字段沾瓦。
HTTP/1.1時(shí)代:持久連接稱為了默認(rèn)的連接方式满着;同時(shí)持久連接的弊病也展現(xiàn)出來(lái),即所有的連接都是串行的贯莺,HOLB风喇;當(dāng)某一個(gè)請(qǐng)求阻塞時(shí)就會(huì)導(dǎo)致同一條連接的后續(xù)請(qǐng)求被阻塞;
為了解決這一問題:提出了pipellining的概念缕探;客戶端發(fā)起一次請(qǐng)求時(shí)不必等待響應(yīng)便直接發(fā)起第二個(gè)請(qǐng)求魂莫;服務(wù)端按照請(qǐng)求的順序一次返回結(jié)果。
我們知道 HTTP 協(xié)議采用“請(qǐng)求-應(yīng)答”模式爹耗,當(dāng)使用普通模式耙考,即非 Keep-Alive 模式時(shí),每個(gè)請(qǐng)求/應(yīng)答客戶和服務(wù)器都要新建一個(gè)連接潭兽,完成之后立即斷開連接(HTTP協(xié)議為無(wú)連接的協(xié)議)倦始;當(dāng)使用 Keep-Alive 模式(又稱持久連接、連接重用)時(shí)山卦,Keep-Alive 功能使客戶端到服務(wù)器端的連接持續(xù)有效鞋邑,當(dāng)出現(xiàn)對(duì)服務(wù)器的后繼請(qǐng)求時(shí),Keep-Alive 功能避免了建立或者重新建立連接账蓉。
- HTTP Keep-Alive 簡(jiǎn)單說(shuō)就是保持當(dāng)前的TCP連接枚碗,避免了重新建立連接。
- HTTP 長(zhǎng)連接不可能一直保持铸本,例如 Keep-Alive: timeout=5, max=100视译,表示這個(gè)TCP通道可以保持5秒,max=100归敬,表示這個(gè)長(zhǎng)連接最多接收100次請(qǐng)求就斷開酷含。
- HTTP是一個(gè)無(wú)狀態(tài)協(xié)議,這意味著每個(gè)請(qǐng)求都是獨(dú)立的汪茧,Keep-Alive沒能改變這個(gè)結(jié)果椅亚。另外,Keep-Alive也不能保證客戶端和服務(wù)器之間的連接一定是活躍的舱污,在HTTP1.1版本中也如此呀舔。唯一能保證的就是當(dāng)連接被關(guān)閉時(shí)你能得到一個(gè)通知,所以不應(yīng)該讓程序依賴于Keep-Alive的保持連接特性,否則會(huì)有意想不到的后果媚赖。
- 使用長(zhǎng)連接之后霜瘪,客戶端、服務(wù)端怎么知道本次傳輸結(jié)束呢惧磺??jī)刹糠郑?. 判斷傳輸數(shù)據(jù)是否達(dá)到了Content-Length 指示的大杏倍浴;2. 動(dòng)態(tài)生成的文件沒有 Content-Length 磨隘,它是分塊傳輸(chunked)缤底,這時(shí)候就要根據(jù) chunked 編碼來(lái)判斷,chunked 編碼的數(shù)據(jù)在最后有一個(gè)空 chunked 塊番捂,表明本次傳輸數(shù)據(jù)結(jié)束个唧。
2.無(wú)狀態(tài)
無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒有記憶能力,服務(wù)器不知道客戶端是什么狀態(tài)设预。即我們給服務(wù)器發(fā)送 HTTP 請(qǐng)求之后徙歼,服務(wù)器根據(jù)請(qǐng)求,會(huì)給我們發(fā)送數(shù)據(jù)過(guò)來(lái)鳖枕,但是魄梯,發(fā)送完,不會(huì)記錄任何信息耕魄。HTTP 是一個(gè)無(wú)狀態(tài)協(xié)議,這意味著每個(gè)請(qǐng)求都是獨(dú)立的彭谁,Keep-Alive 沒能改變這個(gè)結(jié)果吸奴。