原文:http://www.67bar.com/archives/1229html
HTTP由兩部分組成:請求和響應。當你在Web瀏覽器中輸入一個URL時,瀏覽器將根據你的要求建立併發送請求,該請求包含所輸入的URL以及一些與瀏覽器自己相關的信息。當服務器收到這個請求時將返回一個響應,該響應包括與該請求相關的信息以及位於指定URL(若是有的話)的數據。直到瀏覽器解析該響應並顯示出網頁(或其餘資源)爲止。java
HTTP請求瀏覽器
HTTP請求的格式以下所示:緩存
<request-line> <headers> <blank line> [<request-body>]
在HTTP請求中,第一行必須是一個請求行(request line),用來講明請求類型、要訪問的資源以及使用的HTTP版本。服務器
緊接着是一個首部(header)小節,用來講明服務器要使用的附加信息。併發
在首部以後是一個空行,再此以後能夠添加任意的其餘數據[稱之爲主體(body)]。app
在HTTP中,定義了多種請求類型,一般咱們關心的只有GET請求和POST請求。只要在Web瀏覽器上輸入一個URL,瀏覽器就將基於該URL向服務器發送一個GET請求,以告訴服務器獲取並返回什麼資源。對於www.baidu.com的GET請求以下所示:函數
GET / HTTP/1.1 Host: www.baidu.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 Connection: Keep-Alive
請求行的第一部分說明了該請求是GET請求。該行的第二部分是一個斜槓(/),用來講明請求的是該域名的根目錄。該行的最後一部分說明使用的是HTTP 1.1版本(另外一個可選項是1.0)。那麼請求發到哪裏去呢?這就是第二行的內容。編碼
第2行是請求的第一個首部,HOST。首部HOST將指出請求的目的地。結合HOST和上一行中的斜槓(/),能夠通知服務器請求的是www.baidu.com/(HTTP 1.1才須要使用首部HOST,而原來的1.0版本則不須要使用)。第三行中包含的是首部User-Agent,服務器端和客戶端腳本都可以訪問它,它是瀏覽器類型檢測邏輯的重要基礎。該信息由你使用的瀏覽器來定義(在本例中是Firefox 1.0.1),而且在每一個請求中將自動發送。最後一行是首部Connection,一般將瀏覽器操做設置爲Keep-Alive(固然也能夠設置爲其餘值)。注意,在最後一個首部以後有一個空行。即便不存在請求主體,這個空行也是必需的。url
要發送GET請求的參數,則必須將這些額外的信息附在URL自己的後面。其格式相似於:
URL ? name1=value1&name2=value2&..&nameN=valueN
該信息稱之爲查詢字符串(query string),它將會複製在HTTP請求的請求行中,以下所示:
GET /books/?name=Professional%20Ajax HTTP/1.1 Host: www.baidu.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 Connection: Keep-Alive
注意,爲了將文本「Professional Ajax」做爲URL的參數,須要編碼處理其內容,將空格替換成%20,這稱爲URL編碼(URL encoding),經常使用於HTTP的許多地方(JavaScript提供了內建的函數來處理URL編碼和解碼)。「名稱—值」(name—value)對用 & 隔開。絕大部分的服務器端技術可以自動對請求主體進行解碼,併爲這些值的訪問提供一些邏輯方式。固然,如何使用這些數據仍是由服務器決定的。
另外一方面,POST請求在請求主體中爲服務器提供了一些附加的信息。一般,當填寫一個在線表單並提交它時,這些填入的數據將以POST請求的方式發送給服務器。
如下就是一個典型的POST請求:
POST / HTTP/1.1 Host: www.baidu.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 Content-Type: application/x-www-form-urlencoded Content-Length: 40 Connection: Keep-Alive name=Professional%20Ajax&publisher=Wiley
從上面能夠發現, POST請求和GET請求之間有一些區別。首先,請求行開始處的GET改成了POST,以表示不一樣的請求類型。你會發現首部Host和User-Agent仍然存在,在後面有兩個新行。其中首部Content-Type說明了請求主體的內容是如何編碼的。瀏覽器始終以application/ x-www-form- urlencoded的格式編碼來傳送數據,這是針對簡單URL編碼的MIME類型。首部Content-Length說明了請求主體的字節數。在首部Connection後是一個空行,再後面就是請求主體。與大多數瀏覽器的POST請求同樣,這是以簡單的「名稱—值」對的形式給出的,其中name是Professional Ajax,publisher是Wiley。你能夠以一樣的格式來組織URL的查詢字符串參數。
下面是一些最多見的請求頭:
Accept:瀏覽器可接受的MIME類型。 Accept – Charset:瀏覽器可接受的字符集。 Accept – Encoding:瀏覽器可以進行解碼的數據編碼方式,好比gzip。Servlet可以向支持gzip的瀏覽器返回經gzip編碼的HTML頁面。許多情形下這能夠
減小5到10倍的下載時間。
Accept – Language:瀏覽器所但願的語言種類,當服務器可以提供一種以上的語言版本時要用到。 Authorization:受權信息,一般出如今對服務器發送的WWW – Authenticate頭的應答中。 Connection:表示是否須要持久鏈接。若是Servlet看到這裏的值爲「Keep – Alive」,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久鏈接),它就能夠利用持久鏈接的優勢,當頁面包含多個元素時(例如Applet,圖片),顯著地減小下載所須要的時間。要實現這一點,Servlet須要在應答中發送一個Content – Length頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,而後在正式寫出內容以前計算它的大小。 Content – Length:表示請求消息正文的長度。 Cookie:這是最重要的請求頭信息之一,參見後面《Cookie處理》一章中的討論。 From:請求發送者的email地址,由一些特殊的Web客戶程序使用,瀏覽器不會用到它。 Host:初始URL中的主機和端口。 If – Modified – Since:只有當所請求的內容在指定的日期以後又通過修改才返回它,不然返回304「Not Modified」應答。 Pragma:指定「no – cache」值表示服務器必須返回一個刷新後的文檔,即便它是代理服務器並且已經有了頁面的本地拷貝。 Referer:包含一個URL,用戶從該URL表明的頁面出發訪問當前請求的頁面。 User – Agent:瀏覽器類型,若是Servlet返回的內容與瀏覽器類型有關則該值很是有用。 UA – Pixels,UA – Color,UA – OS,UA – CPU:由某些版本的IE瀏覽器所發送的非標準的請求頭,表示屏幕大小、顏色深度、操做系統和CPU類型。
HTTP響應
以下所示,HTTP響應的格式與請求的格式十分相似:
<status-line> <headers> <blank line> [<response-body>]
正如你所見,在響應中惟一真正的區別在於第一行中用狀態信息代替了請求信息。狀態行(status line)經過提供一個狀態碼來講明所請求的資源狀況。如下就是一個HTTP響應的例子:
HTTP/1.1 200 OK Date: Sat, 31 Dec 2005 23:59:59 GMT Content-Type: text/html;charset=ISO-8859-1 Content-Length: 122
<html> <head> <title>Wrox Homepage</title> </head> <body> <!– body goes here –> </body> </html>
在本例中,狀態行給出的HTTP狀態代碼是200,以及消息OK。狀態行始終包含的是狀態碼和相應的簡短消息,以免混亂。最經常使用的狀態碼有:
◆200 (OK): 找到了該資源,而且一切正常。 ◆304 (NOT MODIFIED): 該資源在上次請求以後沒有任何修改。這一般用於瀏覽器的緩存機制。 ◆401 (UNAUTHORIZED): 客戶端無權訪問該資源。這一般會使得瀏覽器要求用戶輸入用戶名和密碼,以登陸到服務器。 ◆403 (FORBIDDEN): 客戶端未能得到受權。這一般是在401以後輸入了不正確的用戶名或密碼。 ◆404 (NOT FOUND): 在指定的位置不存在所申請的資源。
在狀態行以後是一些首部。一般,服務器會返回一個名爲Data的首部,用來講明響應生成的日期和時間(服務器一般還會返回一些關於其自身的信息,儘管並不是是必需的)。接下來的兩個首部你們應該熟悉,就是與POST請求中同樣的Content-Type和Content-Length。在本例中,首部Content-Type指定了MIME類型HTML(text/html),其編碼類型是ISO-8859-1(這是針對美國英語資源的編碼標準)。響應主體所包含的就是所請求資源的HTML源文件(儘管還可能包含純文本或其餘資源類型的二進制數據)。瀏覽器將把這些數據顯示給用戶。
注意,這裏並無指明針對該響應的請求類型,不過這對於服務器並不重要。客戶端知道每種類型的請求將返回什麼類型的數據,並決定如何使用這些數據。