HTTP協議簡介
HTTP協議簡介
在TCP/IP體系結構中,HTTP屬於應用層協議,位於TCP/IP協議的頂層。瀏覽Web時,瀏覽器通過HTTP協議與Web服務器交換信息。這些信息(文檔)類型的格式由MIME定義。
HTTP協議具有以下的特點:
- HTTP按客戶/服務器模式工作
HTTP支持客戶(一般情況是瀏覽器)與服務器的通訊,相互傳輸數據。
HTTP定義的事務處理由以下四步組成:- 客戶與服務器建立連接;
- 客戶向服務器提出請求;
- 如果請求被接受,則服務器送回響應,在響應中包括狀態碼和所需的文件;
- 客戶與服務器斷開連接
一次HTTP操作稱爲一次事務(transaction)。 - HTTP是無狀態的
也就是說,瀏覽器和服務器每進行一次HTTP操作,就建立一次連接,但任務結束就中斷連接。 - HTTP使用元信息作爲頭標
HTTP對所有事務都加了頭標(header)。也就是說,在主要數據前加上一塊信息,稱爲元信息(metainformation)。它使服務器能夠提供正在傳送數據的有關信息。例如,傳送對象是哪種類型,是用哪種語言書寫的等。
從功能上講,HTTP支持四類元信息:一般信息頭標、請求頭標、響應頭標和實體頭標。 - HTTP支持兩種請求和響應格式
HTTP由不同的兩部分組成,一是從瀏覽器發往服務器的請求,二是服務器對客戶的響應。
HTTP支持兩種請求和響應,即簡單請求與完全請求和簡單響應與完全響應。 - HTTP是基於文本的簡單協議
HTTP的請求
HTTP的常用請求方法:
方 法 | 說 明 |
GET | 請求讀取一個Web頁面 |
HEAD | 請求讀取一個Web頁面的頭標 |
PUT | 請求存儲一個Web頁面 |
POST | 附加到命名資源中 |
DELETE | 刪除Web頁面 |
LINK | 連接兩個已有資源 |
UNLINK | 取消兩個資源之間的已有連接 |
HTTP請求的格式如下所示:
<request-line>
<headers>
<blank line>
[<request-body>]
在HTTP請求中,第一行必須是一個請求行(request line),用來說明請求類型、要訪問的資源以及使用的HTTP版本。緊接着是一個首部(header)小節,用來說明服務器要使用的附加信息。在首部之後是一個空行,再此之後可以添加任意的其他數據[稱之爲主體(body)]。
在HTTP中,定義了大量的請求類型,不過Ajax開發人員關心的只有GET請求和POST請求。只要在Web瀏覽器上輸入一個URL,瀏覽器就將基於該URL向服務器發送一個GET請求,以告訴服務器獲取並返回什麼資源。對於URL爲XXX的GET請求如下所示:
GET / HTTP/1.1
Host: XXX
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和上一行中的斜槓(/),可以通知服務器請求的是XXX(HTTP 1.1才需要使用首部HOST,而原來的1.0版本則不需要使用)。第三行中包含的是首部User-Agent,服務器端和客戶端腳本都能夠訪問它,它是瀏覽器類型檢測邏輯的重要基礎。該信息由你使用的瀏覽器來定義(在本例中是Firefox 1.0.1),並且在每個請求中將自動發送。最後一行是首部Connection,通常將瀏覽器操作設置爲Keep-Alive)。注意,在最後一個首部之後有一個空行。即使不存在請求主體,這個空行也是必需的。
如果要獲取一個諸如XXX/xxx的XXX域內的頁面,那麼該請求可能類似於:
GET /xxx/ HTTP/1.1
Host: XXX
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
注意只有第一行的內容發生了變化,它只包含URL中XXX後面的部分。
要發送GET請求的參數,則必須將這些額外的信息附在URL本身的後面。其格式類似於:
該信息稱之爲查詢字符串(query string),它將會複製在HTTP請求的請求行中,如下所示:
GET /xxx/?name=Professional%20Ajax HTTP/1.1
Host: XXX
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
另一方面,POST請求在請求主體中爲服務器提供了一些附加的信息。通常,當填寫一個在線表單並提交它時,這些填入的數據將以POST請求的方式發送給服務器。
以下就是一個典型的POST請求:
POST / HTTP/1.1
Host: XXX
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的查詢字符串參數。
正如前面所提到的,還有其他的HTTP請求類型,它們遵從的基本格式與GET請求和POST請求相同。下一步我們來看看服務器將對HTTP請求發送什麼響應。
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):在指定的位置不存在所申請的資源。
在狀態行之後是一些首部。通常,服務器會返回一個名爲Date的首部,用來說明響應生成的日期和時間(服務器通常還會返回一些關於其自身的信息,儘管並非是必需的)。接下來的兩個首部大家應該熟悉,就是與POST請求中一樣的Content-Type和Content-Length。在本例中,首部Content-Type指定了MIME類型HTML(text/html),其編碼類型是ISO-8859-1(這是針對美國英語資源的編碼標準)。響應主體所包含的就是所請求資源的HTML源文件(儘管還可能包含純文本或其他資源類型的二進制數據)。瀏覽器將把這些數據顯示給用戶。
注意,這裏並沒有指明針對該響應的請求類型,不過這對於服務器並不重要。客戶端知道每種類型的請求將返回什麼類型的數據,並決定如何使用這些數據。
HTTP認證
◆ 基本認證 basic authentication
401 Unauthorized
WWW-Authenticate: Basic realm="WallyWorld"
3. 客戶端將輸入的用戶名密碼用Base64進行編碼後,採用非加密的明文方式傳送給服務器。 Authorization: Basic xxxxxxxxxx.
4. 如果認證成功,則返回相應的資源。如果認證失敗,則仍返回401狀態,要求重新進行認證。◆ 摘要認證 digest authentication
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
realm="[email protected]",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
3. 客戶端將以用戶名,密碼,nonce值,HTTP方法, 和被請求的URI爲校驗值基礎而加密(默認爲MD5算法)的摘要信息返回給服務器。Authorization: Digest
username="Mufasa", ← 客戶端已知信息
realm="[email protected]", ← 服務器端質詢響應信息
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ← 服務器端質詢響應信息
uri="/dir/index.html", ← 客戶端已知信息
qop=auth, ← 服務器端質詢響應信息
nc=00000001, ← 客戶端計算出的信息
cnonce="0a4f113b", ← 客戶端計算出的客戶端nonce
response="6629fae49393a05397450978507c4ef1", ← 最終的摘要信息 ha3
opaque="5ccc069c403ebaf9f0171e9517f40e41" ← 服務器端質詢響應信息
4. 如果認證成功,則返回相應的資源。如果認證失敗,則仍返回401狀態,要求重新進行認證。 ※ nonce:隨機字符串,每次返回401響應的時候都會返回一個不同的nonce。
※ nounce:隨機字符串,每個請求都得到一個不同的nounce。
◆ WSSE(WS-Security)認證
HTTP/1.1 401 Unauthorized
WWW-Authenticate: WSSE
realm="[email protected]",
profile="UsernameToken" ← 服務器期望你用UsernameToken規則生成迴應
※ UsernameToken規則:客戶端生成一個nonce,然後根據該nonce,密碼和當前日時來算出哈希值。Authorization: WSSE profile="UsernameToken"
X-WSSE:UsernameToken
username="Mufasa",
PasswordDigest="Z2Y......",
Nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
Created="2010-01-01T09:00:00Z"
4. 如果認證成功,則返回相應的資源。如果認證失敗,則仍返回401狀態,要求重新進行認證。與HTTP相關類的簡介
WebRequest類
WebRequest 是 .NET Framework 的用於訪問 Internet 數據的請求/響應模型的抽象基類。使用該請求/響應模型的應用程序可以用協議不可知的方式從 Internet 請求數據。在這種方式下,應用程序處理 WebRequest 類的實例,而協議特定的子類則執行請求的具體細節。
請求從應用程序發送到某個特定的 URI,如服務器上的 Web 頁。URI 從一個爲應用程序註冊的 WebRequest 子代列表中確定要創建的適當子類。註冊 WebRequest 子代通常是爲了處理某個特定的協議(如 HTTP 或 FTP),但是也可以註冊它以處理對特定服務器或服務器上的路徑的請求。
由於 WebRequest 類是一個抽象類,所以 WebRequest 實例在運行時的實際行爲由 WebRequest.Create 方法所返回的子類確定。
注意 使用 Create 方法初始化新的 WebRequest 實例。不要使用 WebRequest 構造函數。
下面的示例說明如何創建 WebRequest 實例並返回響應。
// Initialize the WebRequest.
WebRequest myRequest = WebRequest.Create("xxx");
// Return the response.
WebResponse myResponse = myRequest.GetResponse();
// Code to use the WebResponse goes here.
// Close the response to free resources.
myResponse.Close();
WebResponse 類
WebResponse 類是抽象(在 Visual Basic 中爲 MustInherit)基類,協議特定的響應類從該抽象基類派生。應用程序可以使用 WebResponse 類的實例以協議不可知的方式參與請求和響應事務,而從 WebResponse 派生的協議特定的類攜帶請求的詳細信息。
客戶端應用程序不直接創建 WebResponse 對象,而是通過調用 WebRequest 實例上的 GetResponse 方法來創建它。
下面的示例從 WebRequest 創建 WebResponse 實例。
// Initialize the WebRequest.
WebRequest myRequest = WebRequest.Create("xxx");
// Return the response.
WebResponse myResponse = myRequest.GetResponse();
// Code to use the WebResponse goes here.
// Close the response to free resources.
myResponse.Close();
HttpWebRequest 類
HttpWebRequest 類對 WebRequest 中定義的屬性和方法提供支持,也對使用戶能夠直接與使用 HTTP 的服務器交互的附加屬性和方法提供支持。
不要使用
HttpWebRequest 構造函數。使用
WebRequest.Create 方法初始化
HttpWebRequest 的一個新實例。如果 URI 的方案是 http://
或
https://
,則 Create 將返回 HttpWebRequest 實例。
GetResponse 方法向 RequestUri 屬性中指定的 Internet 資源發出同步請求並返回包含該響應的 HttpWebResponse 實例。可以使用 BeginGetResponse 和 EndGetResponse 方法對 Internet 資源發出異步請求。
當要向 Internet 資源發送數據時,GetRequestStream 方法返回用於發送數據的Stream實例。BeginGetRequestStream 和 EndGetRequestStream 方法提供對發送數據流的異步訪問。
下面的示例爲 URI xxx 創建 HttpWebRequest
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("xxx");
HttpWebResponse類
此類包含對 WebResponse 類中的屬性和方法的 HTTP 特定用法的支持。HttpWebResponse 類用於生成發送 HTTP 請求和接收 HTTP 響應的 HTTP 獨立客戶端應用程序。
注意:不要混淆 HttpWebResponse 和 HttpResponse;後者用於 ASP.NET 應用程序,而且它的方法和屬性是通過 ASP.NET 的內部 HttpResponse 對象公開的。
決不要直接創建 HttpWebResponse 類的實例。而應當使用通過調用 HttpWebRequest.GetResponse 所返回的實例。
從 Internet 資源返回的公共標頭信息公開爲該類的屬性。有關完整的列表,請參見下表。可以從 Headers 屬性以名稱/值對的形式讀取其他標頭。
下表顯示可以通過 HttpWebResponse 類的屬性使用的公共 HTTP 標頭。
標頭 | 屬性 |
---|---|
Content-Encoding
|
ContentEncoding
|
Content-Length
|
ContentLength
|
Content-Type
|
ContentType
|
Last-Modified
|
LastModified
|
服務器
|
Server
|
通過調用 GetResponseStream 方法,以 Stream 的形式返回來自 Internet 資源的響應的內容。
下面的示例返回 HttpWebRequest 的 HttpWebResponse:
HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create("xxx");
HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();
// Insert code that uses the response object.
HttpWResp.Close()
URI類
URI 是 Internet 上可由應用程序使用的資源的簡潔表示形式。Uri 類定義了屬性和方法來處理 URI,包括分析、比較和組合。Uri 類屬性是隻讀的,修改 Uri 實例需使用 UriBuilder 類。
Uri 類只存儲絕對 URI。相對 URI(例如“/new/index.htm”)必須相對於基 URI 展開,這樣纔是絕對的。提供了 MakeRelative 方法在必要時將絕對 URI 轉換爲相對 URI。
URI 由轉義編碼存儲爲規範化 URI,所有 ASCII 值大於 127 的字符都被替換爲它們的等效十六進制數。爲使 URI 具有規範化格式,Uri 構造函數執行以下步驟。
- 將 URI 方案轉換爲小寫。
- 將主機名轉換爲小寫。
- 移除默認端口號和空端口號。
- 移除多餘的段(如“/”和“/test”段)以簡化 URI。
使用 ToString 方法,可以將 Uri 類的內容從轉義編碼的 URI 引用轉換爲可讀的 URI 引用。
一些 URI 包括段標識符或查詢。段標識符是 URI 中跟在數字符號 (#) 後的任何文本,存儲在 Fragment 屬性中。查詢信息是 URI 中跟在問號 (?) 後的任何文本,存儲在 Query 屬性中。
注意:URI 類支持使用以下格式的 IP 地址:四組表示法的 IPv4 協議和冒號分隔的十六進制 IPv6 協議。請記住在 IPv6 地址兩邊括上方括號,如 http://[::1]。
下面的示例創建 Uri 類的實例,並用它來創建 WebRequest。
Uri siteUri = new Uri("xxx");
WebRequest wr = WebRequest.Create(siteUri);