細(xì)說HTTP之上篇
每天,都有數(shù)以億萬計(jì)的JPEG圖片、HTML頁面、文本文件、MPEG電影、WAV音頻文件、Java小程序和其他資源在因特網(wǎng)上游弋。HTTP可以從遍布全世界的Web服務(wù)器上將這些信息快速、便捷、可靠的搬移到人們桌面上的Web瀏覽器上去。
HTTP,全稱Hyper Text Transport Protocal,即超文本傳輸協(xié)議,定義了瀏覽器如何向服務(wù)器請(qǐng)求文檔以及服務(wù)器怎樣把文檔傳送給瀏覽器,它是萬維網(wǎng)能夠可靠的交換文件(包括文本,聲音,圖像等多種多媒體文件)的基礎(chǔ)。
起源
超文本傳輸協(xié)議的前身是Xanadu項(xiàng)目,超文本的概念是Ted Nelson在1960年代提出的。1989年,Tim Berners Lee在CERN擔(dān)任軟件咨詢師的時(shí)候,開發(fā)了一套程序,奠定了萬維網(wǎng)的基礎(chǔ)。1990年12月,超文本在CERN首次上線。1991年夏天,繼Telnet等協(xié)議之后,超文本轉(zhuǎn)移協(xié)議成為了互聯(lián)網(wǎng)諸多協(xié)議的一份子。
特點(diǎn)
1、支持客戶/服務(wù)器模式。支持基本認(rèn)證 和安全認(rèn)證。
2、 簡(jiǎn)單快速:客戶向服務(wù)器請(qǐng)求服務(wù)時(shí),只需傳送請(qǐng)求方法和路徑。請(qǐng)求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡(jiǎn)單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快。
3、靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對(duì)象。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記。
4、HTTP 0.9和1.0使用非持續(xù)連接:限制每次連接只處理一個(gè)請(qǐng)求,服務(wù)器處理完客戶的請(qǐng)求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時(shí)間。
HTTP 1.1使用持續(xù)連接:不必為每個(gè)web對(duì)象創(chuàng)建一個(gè)新的連接,一個(gè)連接可以傳送多個(gè)對(duì)象。
5、無狀態(tài):HTTP協(xié)議是 無狀態(tài)協(xié)議 。無狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。
Web客戶端和服務(wù)器交互過程和模型
客戶端/服務(wù)器(client/server)這個(gè)術(shù)語可追溯到上個(gè)千年(20世紀(jì)80年代),表示通過網(wǎng)絡(luò)連接起來的個(gè)人計(jì)算機(jī)??蛻舳?服務(wù)器也可用于描述兩個(gè)計(jì)算機(jī)程序的關(guān)系--客戶程序和服務(wù)器程序??蛻粝蚍?wù)器請(qǐng)求某種服務(wù)(比如請(qǐng)求一個(gè)文件或數(shù)據(jù)庫訪問),服務(wù)器滿足請(qǐng)求并通過網(wǎng)絡(luò)將結(jié)果傳送給客戶端。雖然客戶端和服務(wù)器程序可存在于同一臺(tái)計(jì)算機(jī)中,但它們通常都運(yùn)行在不同計(jì)算機(jī)上。一臺(tái)服務(wù)器處理多個(gè)客戶端請(qǐng)求也是很常見的。
最常見的Web客戶端就是瀏覽器了,一次請(qǐng)求/響應(yīng)的模型如下圖所示:

這里需要說明的一點(diǎn)是,每次訪問一個(gè)靜態(tài)資源,比如一個(gè)html文件,一個(gè)png圖片或者一個(gè)文本文檔都會(huì)向服務(wù)器發(fā)出一個(gè)HTTP請(qǐng)求,每個(gè)HTTP請(qǐng)求都會(huì)經(jīng)歷上圖的請(qǐng)求/響應(yīng)模型。比如我們點(diǎn)開http://www.taobao.com/(淘寶網(wǎng)),我們會(huì)往服務(wù)器發(fā)送成百上千個(gè)HTTP請(qǐng)求,收到來自客戶端的請(qǐng)求后,服務(wù)器會(huì)去尋找相應(yīng)的資源,如果成功,就將對(duì)象,對(duì)象類型,對(duì)象長(zhǎng)度以及其他信息放在HTTP響應(yīng)中發(fā)回客戶端。那么問題來了,服務(wù)器怎么去尋找相應(yīng)的資源,憑據(jù)是什么?
URL與資源
URL是瀏覽器尋找信息時(shí)所需要的資源位置。通過URL,人類和應(yīng)用程序才能找到使用并共享因特網(wǎng)上大量的數(shù)據(jù)資源。URL是人們對(duì)HTTP和其他協(xié)議的常用訪問點(diǎn):在瀏覽器中輸入一串URL,瀏覽器就會(huì)在幕后發(fā)送適當(dāng)?shù)膮f(xié)議報(bào)文來獲取人們所期望的資源。
URL的語法
大多數(shù)的URL方案的URL語法都建立在這個(gè)由9部分的通用格式上:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
幾乎沒有哪個(gè)URL中包含了所有這些組件。URL最重要的3個(gè)部分是方案(scheme)、主機(jī)(host)和路徑(path)。
目前常見的協(xié)議類型有很多種,常用的有http,https(更安全的http),mailto(郵件),ftp(文件傳輸),rtsp(音頻視頻),file,news,telnet等等。#p#
HTTP報(bào)文
HTTP報(bào)文是在HTTP應(yīng)用程序之間發(fā)送的數(shù)據(jù)塊。這些數(shù)據(jù)塊以一些文本形式的元信息開頭,這些信息描述了報(bào)文的內(nèi)容和含義,后面跟著可選的數(shù)據(jù)部分。
報(bào)文的組成
HTTP報(bào)文是簡(jiǎn)單的格式化數(shù)據(jù)塊。每一條報(bào)文都包含一條來自客戶端的請(qǐng)求,或者來自服務(wù)器的響應(yīng)。它們有三個(gè)部分組成:對(duì)報(bào)文進(jìn)行描述的起始行(start line)、包含屬性的首部塊(header),以及可選的、包含數(shù)據(jù)的主體部分(body)。
- HTTP/1.0 200 OK //起始行
- Content-type:text/plain //首部
- Content-length:19 //首部
- Hi I'm a message! //主體
報(bào)文的語法
所有的HTTP報(bào)文可以分為兩類:請(qǐng)求報(bào)文(request message)和響應(yīng)報(bào)文(response message)。請(qǐng)求報(bào)文會(huì)向服務(wù)器發(fā)送一個(gè)請(qǐng)求,響應(yīng)報(bào)文會(huì)將結(jié)果返回個(gè)客戶端。
請(qǐng)求報(bào)文的格式:
- <method> <request-UTL> <version>
- <headers>
- <entity-body>
響應(yīng)報(bào)文格式:
- <version> <status><reason-phrase>
- <header>
- <entity-body>
下面是對(duì)格式中各部分的簡(jiǎn)要描述
1、方法(method) GET
客戶端希望服務(wù)器對(duì)資源執(zhí)行的動(dòng)作。是一個(gè)單獨(dú)的詞,比如GET、HEAD或POST。
2、請(qǐng)求的URL(request-URL)
命名了所有請(qǐng)求資源,或者URL路徑組件的完整URL。如果直接與服務(wù)器進(jìn)行對(duì)話,只要URL的路徑組件是資源的絕對(duì)路徑,通常就不會(huì)有什么問題--服務(wù)器可以假定 義自己是URL的主機(jī)/端口。
3、版本(version) HTTP/1.1
報(bào)文所使用的HTTP版本,其格式如下:
HTTP/<major>.<minor>
其中主要版本號(hào)(major)和次要版本號(hào)(minor)都是整數(shù)。
4、狀態(tài)碼(status)
這三個(gè)數(shù)字描述了請(qǐng)求過程中所發(fā)生的情況。每個(gè)狀態(tài)碼的第一位數(shù)字都用于描述狀態(tài)的一般類別("成功"、"出錯(cuò)"等)。
5、原因短語(reason-phrase)
數(shù)字狀態(tài)碼的可讀版本,包含行終止序列之前的所有文本。原因短語只是給人類看的,它不能說明什么??蛻舳艘廊徊捎脿顟B(tài)碼來判斷請(qǐng)求/響應(yīng)是否成功!
例如:HTTP/1.0 200 NOT OK 客戶端依然會(huì)當(dāng)請(qǐng)求已成功處理。因?yàn)闋顟B(tài)碼是200。而原因短語只是說明而已,這對(duì)于自定義擴(kuò)展?fàn)顟B(tài)碼還是比較有用的。
6、首部(header)
可以有0個(gè)或多個(gè)首部,每個(gè)首部都包含一個(gè)名字,后面跟著一個(gè)冒號(hào)(:),然后是一個(gè)可選的空格,接著是一個(gè)值,最后是一個(gè)CRLF。首部是由一個(gè) 空行 (CRLF)結(jié)束 的,表示了首部列表的結(jié)束和實(shí)體主體的開始。
7、實(shí)體的主體部分(entity-body)
實(shí)體的主體部分包含一個(gè)由任意數(shù)據(jù)組成的數(shù)據(jù)塊。并不是所有的報(bào)文都包含實(shí)體的主體部分。如GET請(qǐng)求就不包含實(shí)體。