.Net HTTP請求的發送方式與分析


注:以下內容均來源於網絡。

https://blog.csdn.net/chen213wb/article/details/81747573

https://blog.csdn.net/qq_23034515/article/details/89226635

https://www.cjavapy.com/article/50/

。。。

HTTP常用請求參數

Method

請求方式:Get、Post、Put、Delete

Timeout

獲取或設置請求的超時值。(毫秒)

ReadWriteTimeout

獲取或設置讀取或寫入流時的超時

KeepAlive

獲取或設置一個值,該值指示是否與 Internet 資源建立持久性連接。

ClientCertificates

獲取或設置與此請求關聯的安全證書集合

Proxy

獲取或設置請求的代理信息。

AllowAutoRedirect

獲取或設置一個值,該值指示請求是否應跟隨重定向響應。

CookieContainer

獲取或設置與此請求關聯的cookie。

Credentials

獲取或設置請求的身份驗證信息。

MaximumAutomaticRedirections

獲取或設置請求將跟隨的重定向的最大數目。

SendChunked

獲取或設置一個值,該值指示是否將數據分段發送到 Internet 資源。

Header.ContentType

設置請求的數據類型:application/x-www-form-urlencoded、multipart/form-data、application/json、text/xml...

Header.ContentLength

設置請求的數據長度

Header.Accept

設置響應的數據類型:application/x-www-form-urlencoded、multipart/form-data、application/json、text/xml...

Header.UserAgent

客戶端的訪問類型,包括瀏覽器版本和操作系統信息

Header.Referer

請求的來源地址

 

請求方式:

1、GET請求會向數據庫發索取數據的請求,從而來獲取信息,該請求就像數據庫的select操作一樣,只是用來查詢一下數據,不會修改、增加數據,不會影響資源的內容,即該請求不會產生副作用。無論進行多少次操作,結果都是一樣的。

2、與GET不同的是,PUT請求是向服務器端發送數據的,從而改變信息,該請求就像數據庫的update操作一樣,用來修改數據的內容,但是不會增加數據的種類等,也就是說無論進行多少次PUT操作,其結果並沒有不同。

3、POST請求同PUT請求類似,都是向服務器端發送數據的,但是該請求會改變數據的種類等資源,就像數據庫的insert操作一樣,會創建新的內容。幾乎目前所有的提交操作都是用POST請求的。

4、DELETE請求顧名思義,就是用來刪除某一個資源的,該請求就像數據庫的delete操作。

就像前面所講的一樣,既然PUT和POST操作都是向服務器端發送數據的,那么兩者有什么區別呢?POST主要作用在一個集合資源之上的(url),而PUT主要作用在一個具體資源之上的(url/xxx),通俗一下講就是,如URL可以在客戶端確定,那么可使用PUT,否則用POST。

綜上所述,我們可理解為以下:

1、GET     /url/xxx  查看

2、PUT     /url/xxx  更新

3、POST    /url      創建  

4、DELETE  /url/xxx  刪除  

 

數據類型:

1、application/x-www-form-urlencoded

瀏覽器的原生 form 表單,如果不設置 enctype 屬性,那么最終就會以 application/x-www-form-urlencoded 方式提交數據。提交的數據按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉碼。大部分服務端語言都對這種方式有很好的支持。

2、multipart/form-data

我們使用表單上傳文件時,必須讓 form 的 enctyped 等於這個值。
種方式一般用來上傳文件時必須使用該種方式,各大服務端語言對它也有着良好的支持。

3、application/json

這個 Content-Type 作為響應頭大家肯定不陌生。實際上,現在越來越多的人把它作為請求頭,用來告訴服務端消息主體是序列化后的 JSON 字符串。由於 JSON 規范的流行,除了低版本 IE 之外的各大瀏覽器都原生支持 JSON.stringify,服務端語言也都有處理 JSON 的函數,使用 JSON 不會遇上什么麻煩。JSON 格式支持比鍵值對復雜得多的結構化數據,這一點也很有用。

4、text/xmlXML-RPC

協議簡單、功能夠用,各種語言的實現都有。它的使用也很廣泛,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服務等等。JavaScript 中,也有現成的庫支持以這種方式進行數據交互,能很好的支持已有的 XML-RPC 服務。 因XML 結構還是過於臃腫,一般場景用 JSON 會更靈活方便。

 

.NET發送HTTP請求的方式

1、HttpWebRequest

這是.NET創建者最初開發用於使用HTTP請求的標准類。使用HttpWebRequest可以讓開發者控制請求/響應流程的各個方面,如 timeouts, cookies, headers, protocols。另一個好處是HttpWebRequest類不會阻塞UI線程。例如,當您從響應很慢的API服務器下載大文件時,您的應用程序的UI不會停止響應。HttpWebRequest通常和WebResponse一起使用,一個發送請求,一個獲取數據。HttpWebRquest更為底層一些,能夠對整個訪問過程有個直觀的認識,但同時也更加復雜一些。

這種方法是早期開發者使用的方法,在當前業務中已經很少使用,由於其更加底層,需要處理一些細節,最多用於框架內部操作。

    /// <summary>
    /// 1.通過WebRequest發送請求
    /// </summary>
    public class SendByWebRequest
    {
        public static string Post(string url,string content)
        {
            HttpWebRequest request = null;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(url);
                var data = Encoding.UTF8.GetBytes(content);
                request.Accept = "application/json"; // 設置響應數據的ContentType
                request.Method = "POST";
                request.ContentType = "application/json"; // 設置請求數據的ContentType
                request.ContentLength = data.Length;
                // 設置入參
                using (var stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                // 發送請求
                var response = (HttpWebResponse)request.GetResponse();
                // 讀取出參
                using (var resStream = response.GetResponseStream())
                {
                    using (var reader = new StreamReader(resStream, Encoding.UTF8))
                    {
                        return reader.ReadToEnd();
                    }
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                // 釋放連接
                if (request != null) request.Abort();
            }
        }

        public static string Get(string url, string content)
        {
            HttpWebRequest request = null;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(url + content);
                request.Accept = "application/json"; // 設置響應數據的ContentType
                var response = (HttpWebResponse)request.GetResponse();
                // 讀取出參
                using (var resStream = response.GetResponseStream())
                {
                    using (var reader = new StreamReader(resStream, Encoding.UTF8))
                    {
                        return reader.ReadToEnd();
                    }
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                // 釋放連接
                if (request != null) request.Abort();
            }
        }
    }

 

2、WebClient

WebClient是一種更高級別的抽象,是HttpWebRequest為了簡化最常見任務而創建的,使用過程中你會發現他缺少基本的header,timeoust的設置,不過這些可以通過繼承httpwebrequest來實現。相對來說,WebClient比WebRequest更加簡單,它相當於封裝了request和response方法,不過需要說明的是,Webclient和WebRequest繼承的是不同類,兩者在繼承上沒有任何關系。

使用WebClient可能比HttpWebRequest直接使用更慢(大約幾毫秒),但卻更為簡單,減少了很多細節,代碼量也比較少。

WebClient主要面向了WEB網頁場景,在模擬Web操作時使用較為方便,但用在RestFul場景下卻比較麻煩,這時候就需要HttpClient出馬了。

    /// <summary>
    /// 2.通過WebClient發送請求
    /// </summary>
    public class SendByWebClient
    {
        public static string Post(string url, string content)
        {
            try
            {
                byte[] para = Encoding.UTF8.GetBytes(content);
                using (var client = new WebClient())
                {
                    client.Encoding = Encoding.UTF8;
                    client.Headers.Add("Accept", "application/json"); // 設置響應數據的ContentType
                    client.Headers.Add("Content-Type", "application/json"); // 設置請求數據的ContentType
                    client.Headers.Add("ContentLength", para.Length.ToString());
                    var response = client.UploadData(url, "POST", para);
                    return Encoding.UTF8.GetString(response);
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static string Get(string url, string content)
        {
            try
            {
                using (var client = new WebClient())
                {
                    client.Encoding = Encoding.UTF8;
                    client.Headers.Add("Accept", "application/json"); // 設置響應數據的ContentType
                    return client.DownloadString(url + content);
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

 

 

3、HttpClient

目前業務上使用的比較多的是HttpClient,它適合用於多次請求操作,一般設置好默認頭部后,可以進行重復多次的請求,基本上用一個實例可以提交任何的HTTP請求。此外,HttpClient提供了異步支持,可以輕松配合async await 實現異步請求。

HttpClient推薦使用單一實例共享使用,發關請求的方法推薦使用異步的方式。

    /// <summary>
    /// 3.通過HttpClient發送請求
    /// </summary>
    public class SendByHttpClient
    {
        public static string Post(string url, string content)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    
                    client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); // 設置響應數據的ContentType
                    var para = new StringContent(content);
                    para.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); // 設置請求數據的ContentType
                    return client.PostAsync(url, para).Result.Content.ReadAsStringAsync().Result;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static string Get(string url, string content)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); // 設置響應數據的ContentType
                    return client.GetStringAsync(url + content).Result;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }


    }

 

4、第三方類庫

Flurl.Http,RestSharp等。

    /// <summary>
    /// 4.通過第三方類庫發送請求
    /// </summary>
    public class SendByFlurl
    {
        public static string Post(string url, string content)
        {
            try
            {
                //string abc = $"{url}".PostJsonAsync(content).ReceiveString().Result;
                return $"{url}".PostAsync(new StringContent(content, Encoding.UTF8, "application/json")).ReceiveString().Result;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static string Get(string url, string content)
        {
            try
            {
                return $"{url}{content}".GetStringAsync().Result;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

 

 

 

HttpWebRequset

WebClient

HttpClient

命名空間

System.Net

System.Net

System.Net.Http

繼承類

WebRequest

Component

HttpMessageInvoker

支持url轉向

支持cookie和session

支持用戶代理服務器

使用復雜度

 

 

擴展

REST & RPC

  微服務之間的接口調用通常包含兩個部分,序列化和通信協議。常見的序列化協議包括json、xml、hession、protobuf、thrift、text、bytes等;通信比較流行的是http、soap、websockect,RPC通常基於TCP實現,常用框架例如dubbo,netty、mina、thrift。

  REST:嚴格意義上說接口很規范,操作對象即為資源,對資源的四種操作(post、get、put、delete),並且參數都放在URL上,但是不嚴格的說Http+json、Http+xml,常見的http api都可以稱為Rest接口。

  RPC:即我們常說的遠程過程調用,就是像調用本地方法一樣調用遠程方法,通信協議大多采用二進制方式。

HTTP vs 高性能二進制協議

  HTTP相對更規范,更標准,更通用,無論哪種語言都支持HTTP協議。如果你是對外開放API,例如開放平台,外部的編程語言多種多樣,你無法拒絕對每種語言的支持,相應的,如果采用HTTP,無疑在你實現SDK之前,支持了所有語言,所以,現在開源中間件,基本最先支持的幾個協議都包含RESTful。

  RPC協議性能要高的多,例如Protobuf、Thrift、Kyro等,(如果算上序列化)吞吐量大概能達到http的二倍。響應時間也更為出色。千萬不要小看這點性能損耗,公認的,微服務做的比較好的,例如,netflix、阿里,曾經都傳出過為了提升性能而合並服務。如果是交付型的項目,性能更為重要,因為你賣給客戶往往靠的就是性能上微弱的優勢。

  所以,最佳實踐一般是對外REST,對內RPC,但是追求極致的性能會消耗很多額外的成本,所以一般情況下對內一般也REST,但對於個別性能要求較高的接口使用RPC。

 


免責聲明!

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



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