發送HTTP請求


 

前言

最近一直在做C# winform客戶端項目,因為涉及到和服務器交互,所以研究了一下C#的HTTP網絡編程。

Http通信是通過Http請求報文和Http應答報文來實現的。

由於我開發的是客戶端,所以主要工作就在於封裝Http請求報文,以及收到應答報文后解析數據。


Http請求報文是什么樣的

如果你使用的是chrome瀏覽器,按F12就可以開啟調試模式。現在主流的瀏覽器應該都支持這個功能。隨便打開一個網頁,觸發一個超鏈接請求,應該就能抓取到Http請求報文。

舉個例子,以下是一個Http請求報文的截取內容。

我們可以看到請求報文中有很多參數,這里不一一詳解各個參數的意義。

 


C#中實現Http請求

我個人認為,發送Http請求報文主要有四個步驟

1.       初始化HttpWebRequest(需要引用System.Net)

2.       封裝Http cookie

3.       封裝Http報文頭

4.       封裝請求內容,並將封裝好的請求報文用Stream類寫入流(需要引用System.IO

5.       接收應答報文

接下來,我們一步一步來講解如何在C#中完成Http請求報文的封裝。

初始化HttpWebRequest

使用請求地址作為參數,初始化一個HttpWebRequest實例。

// 初始化HttpWebRequest
HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(strRequestUri);

 

封裝Http cookie

首先,簡單說明一下Cookie。有時也用其復數形式Cookies,指某些網站為了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數據(通常經過加密)。本文為了示例,就以比較簡單的形式展現。

在C#中,使用Cookie類來封裝cookie,以鍵值對的形式保存。

然后,將這個封裝好的cookie添加到CookieContainer容器中,最后填入HttpWebRequest。既然是容器,顧名思義,可以添加多個cookie。

// 封裝Cookie
Uri uri = new Uri(strRequestUri);

Cookie cookie = new Cookie("Name", strCookie); // 設置key、value形式的Cookie
CookieContainer cookies = new CookieContainer();

cookies.Add(uri, cookie);
httpRequest.CookieContainer = cookies;


封裝Http Header

根據自己要發送的請求報文類型來填充Http報文頭。

以下是一個簡單范例:

復制代碼
// 封裝Http Header
httpRequest.Method = "Post";

httpRequest.Referer = strReferer;
httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36";
httpRequest.Accept = "text/plain, */*; q=0.01";
httpRequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
httpRequest.Timeout = 1000 * 30;
httpRequest.KeepAlive = true;
復制代碼

 

填充Http content,並寫入流

首先,將要寫入的內容轉為byte數組(假設是文本內容)。將數組長度填入HttpWebRequest的ContentLength字段。

通過GetRequestStream()獲取HttpWebRequest的請求流。使用這個流對象寫入數組內容。

最后,千萬不要忘記關閉流。本人在開發C#客戶端和Java服務器交互過程中,就遇到這個問題。由於忘記關閉流,Java服務器在解析請求報文時,總是提示不能識別流的結尾。

// 通過流寫入請求數據
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strContent); // 編碼形式按照個人需求來設置
httpRequest.ContentLength = bytes.Length;

Stream requestStream = httpRequest.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close(); // 不要忘記關閉流

 

獲得應答報文

通過流將請求報文發出去后,可以通過HttpWebRequest的GetResponse()方法來獲取HttpWebResponse

// 獲得應答報文
HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();

Stream responseStream = httpResponse.GetResponseStream();
StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
string strResponse = reader.ReadToEnd();
reader.Close();
responseStream.Close();

至此,Http請求過程結束。大家有疑問的地方,歡迎和我探討。

過兩天,我再整理一下上傳文件的 Http方法。

 

附上完整方法

復制代碼
public static void PackageHttpRequest(string strRequestUri, string strReferer, string strContent, string strCookie)
{
    // 初始化HttpWebRequest
    HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(strRequestUri);


    // 封裝Cookie
    Uri uri = new Uri(strRequestUri);

    Cookie cookie = new Cookie("Name", strCookie); // 設置key、value形式的Cookie
    CookieContainer cookies = new CookieContainer();

    cookies.Add(uri, cookie);
    httpRequest.CookieContainer = cookies;

    // 封裝Http Header
    httpRequest.Method = "Post";

    httpRequest.Referer = strReferer;
    httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36";
    httpRequest.Accept = "text/plain, */*; q=0.01";
    httpRequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
    httpRequest.Timeout = 1000 * 30;
    httpRequest.KeepAlive = true;

    // 通過流寫入請求數據
    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strContent); // 編碼形式按照個人需求來設置
    httpRequest.ContentLength = bytes.Length;

    Stream requestStream = httpRequest.GetRequestStream();
    requestStream.Write(bytes, 0, bytes.Length);
    requestStream.Close(); // 不要忘記關閉流

    
// 獲得應答報文
    HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();

    Stream responseStream = httpResponse.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
    string strResponse = reader.ReadToEnd();
    reader.Close();
    responseStream.Close();
}
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM