HTTP協議簡介
既然是基於HTTP協議開發,那麼就首先要了解下HTTP協議的相關內容~html
在TCP/IP體系結構中,HTTP屬於應用層協議,位於TCP/IP協議的頂層。瀏覽Web時,瀏覽器經過HTTP協議與Web服務器交換信息。這些信息(文檔)類型的格式由MIME定義。git
HTTP協議具備如下的特色:github
一次HTTP操做稱爲一次事務(transaction)。 |
HTTP請求的格式以下所示:數組
1 <request-line> 2 <headers> 3 <blank line> 4 [<request-body>]
在HTTP請求中,第一行必須是一個請求行(request line),用來講明請求類型、要訪問的資源以及使用的HTTP版本。緊接着是一個首部(header)小節,用來講明服務器要使用的附加信息。在首部以後是一個空行,再此以後能夠添加任意的其餘數據[稱之爲主體(body)]。
在HTTP中,定義了大量的請求類型,不過Ajax開發人員關心的只有GET請求和POST請求。只要在Web瀏覽器上輸入一個URL,瀏覽器就將基於該URL向服務器發送一個GET請求,以告訴服務器獲取並返回什麼資源。對於URL爲XXX的GET請求以下所示:瀏覽器
1 GET / HTTP/1.1 2 Host: XXX 3 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) 4 Gecko/20050225 Firefox/1.0.1 5 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域內的頁面,那麼該請求可能相似於:服務器
1 GET /xxx/ HTTP/1.1 2 Host: XXX 3 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) 4 Gecko/20050225 Firefox/1.0.1 5 Connection: Keep-Alive
要發送GET請求的參數,則必須將這些額外的信息附在URL自己的後面。其格式相似於:網絡
該信息稱之爲查詢字符串(query string),它將會複製在HTTP請求的請求行中,以下所示app
1 GET /xxx/?name=Professional%20Ajax HTTP/1.1 2 Host: XXX 3 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) 4 Gecko/20050225 Firefox/1.0.1 5 Connection: Keep-Alive
如下就是一個典型的POST請求:異步
1 POST / HTTP/1.1 2 Host: XXX 3 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) 4 Gecko/20050225 Firefox/1.0.1 5 Content-Type: application/x-www-form-urlencoded 6 Content-Length: 40 7 Connection: Keep-Alive 8 name=Professional%20Ajax&publisher=Wiley
正如前面所提到的,還有其餘的HTTP請求類型,它們聽從的基本格式與GET請求和POST請求相同。下一步咱們來看看服務器將對HTTP請求發送什麼響應。
HTTP響應
以下所示,HTTP響應的格式與請求的格式十分相似:
1 <status-line> 2 <headers> 3 <blank line> 4 [<response-body>]
正如你所見,在響應中惟一真正的區別在於第一行中用狀態信息代替了請求信息。狀態行(status line)經過提供一個狀態碼來講明所請求的資源狀況。如下就是一個HTTP響應的例子:
1 HTTP/1.1 200 OK 2 Date: Sat, 31 Dec 2005 23:59:59 GMT 3 Content-Type: text/html;charset=ISO-8859-1 4 Content-Length: 122 5 6 <html> 7 <head> 8 <title>Wrox Homepage</title> 9 </head> 10 <body> 11 <!-- body goes here --> 12 </body> 13 </html>
在本例中,狀態行給出的HTTP狀態代碼是200,以及消息OK。狀態行始終包含的是狀態碼和相應的簡短消息,以免混亂。最經常使用的狀態碼有:
在狀態行以後是一些首部。一般,服務器會返回一個名爲Date的首部,用來講明響應生成的日期和時間(服務器一般還會返回一些關於其自身的信息,儘管並不是是必需的)。接下來的兩個首部你們應該熟悉,就是與POST請求中同樣的Content-Type和Content-Length。在本例中,首部Content-Type指定了MIME類型HTML(text/html),其編碼類型是ISO-8859-1(這是針對美國英語資源的編碼標準)。響應主體所包含的就是所請求資源的HTML源文件(儘管還可能包含純文本或其餘資源類型的二進制數據)。瀏覽器將把這些數據顯示給用戶。
注意,這裏並無指明針對該響應的請求類型,不過這對於服務器並不重要。客戶端知道每種類型的請求將返回什麼類型的數據,並決定如何使用這些數據
WebRequest類
WebRequest 是 .NET Framework 的用於訪問 Internet 數據的請求/響應模型的抽象基類。使用該請求/響應模型的應用程序能夠用協議不可知的方式從 Internet 請求數據。在這種方式下,應用程序處理 WebRequest 類的實例,而協議特定的子類則執行請求的具體細節。
請求從應用程序發送到某個特定的 URI,如服務器上的 Web 頁。URI 從一個爲應用程序註冊的WebRequest 子代列表中肯定要建立的適當子類。註冊 WebRequest 子代一般是爲了處理某個特定的協議(如 HTTP 或 FTP),可是也能夠註冊它以處理對特定服務器或服務器上的路徑的請求。
因爲 WebRequest 類是一個抽象類,因此 WebRequest 實例在運行時的實際行爲由 WebRequest.Create 方法所返回的子類肯定。
注意 使用 Create 方法初始化新的 WebRequest 實例。不要使用 WebRequest 構造函數。
下面的示例說明如何建立 WebRequest 實例並返回響應。
1 // Initialize the WebRequest. 2 WebRequest myRequest = WebRequest.Create("xxx"); 3 // Return the response. 4 WebResponse myResponse = myRequest.GetResponse(); 5 // Code to use the WebResponse goes here. 6 // Close the response to free resources. 7 myResponse.Close();
WebResponse 類
WebResponse 類是抽象(在 Visual Basic 中爲 MustInherit)基類,協議特定的響應類從該抽象基類派生。應用程序可使用 WebResponse 類的實例以協議不可知的方式參與請求和響應事務,而從 WebResponse 派生的協議特定的類攜帶請求的詳細信息。
客戶端應用程序不直接建立 WebResponse 對象,而是經過調用 WebRequest 實例上的GetResponse 方法來建立它。
下面的示例從 WebRequest 建立 WebResponse 實例。
1 // Initialize the WebRequest. 2 WebRequest myRequest = WebRequest.Create("xxx"); 3 // Return the response. 4 WebResponse myResponse = myRequest.GetResponse(); 5 // Code to use the WebResponse goes here. 6 // Close the response to free resources. 7 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
1 HttpWebRequest myReq =(HttpWebRequest)WebRequest.Create("xxx");
經過調用 GetResponseStream 方法,以 Stream 的形式返回來自 Internet 資源的響應的內容。
下面的示例返回 HttpWebRequest 的 HttpWebResponse:
1 HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create("xxx"); 2 HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse(); 3 // Insert code that uses the response object. 4 HttpWResp.Close()
1 Uri siteUri = new Uri("xxx"); 2 WebRequest wr = WebRequest.Create(siteUri);
建立一個test的aspx頁面
建立獲取請求方法
1 public string GetPost() 2 { 3 if ("POST" == Request.RequestType) 4 { 5 System.IO.Stream sm = Request.InputStream;//獲取post正文 6 int len = (int)sm.Length;//post數據長度 7 byte[] inputByts = new byte[len];//字節數據,用於存儲post數據 8 sm.Read(inputByts, 0, len);//將post數據寫入byte數組中 9 sm.Close();//關閉IO流 10 //**********下面是把字節數組類型轉換成字符串********** 11 string data = Encoding.GetEncoding("UTF-8").GetString(inputByts);//轉爲unicode編碼 12 //data = Server.UrlDecode(data);//url參數用到. 13 return data; 14 } 15 else 16 return null; 17 }
在Load中使用Response
1 string res = GetPost(); 2 Response.Write(res);
新建一個解決方案調用上述程序
Main方法中代碼以下所示:
1 string ss = "hello world!"; 2 Encoding encoding = Encoding.GetEncoding("utf-8"); 3 byte[] bytesToPost = encoding.GetBytes(ss); 4 string res = Post("http://localhost:23094/test.aspx", bytesToPost); 5 Console.WriteLine(res); 6 Console.ReadLine();
其中Post方法傳入url和bytesToPost
1 private static string Post(string url, byte[] bytesToPost) 2 { 3 if (String.IsNullOrEmpty(url)) 4 return "url參數爲空值"; 5 if (bytesToPost == null) 6 return "post數據爲空值"; 7 string ResponseString = ""; 8 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 9 System.Net.ServicePointManager.DefaultConnectionLimit = 50; 10 request.KeepAlive = false; 11 request.Method = "POST"; 12 request.ContentType = "text/xml";//提交xml 13 request.ContentLength = bytesToPost.Length; 14 Stream writer = request.GetRequestStream(); 15 writer.Write(bytesToPost, 0, bytesToPost.Length); 16 HttpWebResponse HttpWebRespon = (HttpWebResponse)request.GetResponse(); 17 StreamReader myStreamReader = new StreamReader(HttpWebRespon.GetResponseStream(), Encoding.UTF8); 18 ResponseString = myStreamReader.ReadToEnd(); 19 myStreamReader.Close(); 20 21 writer.Flush(); 22 if (writer != null) 23 { 24 writer.Close(); 25 } 26 if (request != null) 27 { 28 request.Abort(); 29 } 30 return ResponseString; 31 }
效果,先運行Demo 程序再運行調用程序便可看到以下效果
請求成功,返回結果
PS:具體代碼執行過程你們能夠下完Demo後自行debug看看,代碼灰常簡單,算是最簡單的http請求和響應以及調用的流程了,在複雜的過程也是基於這個流程來執行的
https://github.com/XiaoYong666/Http-interface-call
注:介紹部份內容轉載摘抄自網絡,如有文章雷同,請評論留言~定會及時註明出處