(轉)HTTP協議及其POST與GET操作差異 & C#中如何使用POST、GET等

引言

HTTP協議我想任何IT人士都耳熟能詳了,大家都能說出個所以然來。但是如果我問你HTTP協議的請求方法有哪些?POST與GET的差異?GET或POST傳送數據量的大小有限制嗎?HTTP響應的狀態有哪些?以及在C#中你如何使用?如果你不能清楚地回答其中的大部分問題,那么這篇文章就是為你準備的!大綱如下:

1、HTTP概述

1.1、HTTP協議的客戶端與服務器的交互

1.2、HTTP消息

1.3、HTTP請求的方法

1.4、HTTP響應的代碼

2、抓包分析

3、POST與GET的差異

4、以一個實例說明C#中如何使用POST、GET等操作

4.1、HttpWebRequest

4.2、HttpWebResponse

4.3、編寫WinForm程序打開博客園首頁(附源碼)

1、HTTP概述

為了喚醒你對HTTP協議的記憶或使你能夠對HTTP協議有所了解,首先簡單一下HTTP協議。超文本傳輸協議HTTPHyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網絡協議。所有的WWW文件都必須遵守這個標準。設計HTTP最初的目的是為了提供一種發布和接收HTML頁面的方法。

HTTP的發展是萬維網協會(World Wide Web Consortium)和Internet工作小組(Internet Engineering Task Force)合作的結果,(他們)最終發布了一系列的RFC,其中最著名的就是RFC 2616RFC 2616定義了HTTP協議中一個現今被廣泛使用的版本——HTTP 1.1。

1.1、HTTP協議的客戶端與服務器的交互

HTTP是一個客戶端和服務器端請求和應答的標準(TCP)。客戶端是終端用戶服務器端是網站。通過使用Web瀏覽器、網絡爬蟲或者其它的工具,客戶端發起一個到服務器上指定端口(默認端口為80)的HTTP請求。(我們稱這個客戶端)調用戶代理(user agent)。應答的服務器上存儲著(一些)資源,比如HTML文件和圖像。(我們稱)這個應答服務器為源服務器(origin server)。在用戶代理和源服務器中間可能存在多個中間層,比如代理,網關,或者隧道(tunnel)。盡管TCP/IP協議是互聯網上最流行的應用,HTTP協議并沒有規定必須使用它和(基于)它支持的層。事實上,HTTP可以在任何其他互聯網協議上,或者在其他網絡上實現。HTTP只假定(其下層協議提供)可靠的傳輸,任何能夠提供這種保證的協議都可以被其使用。

通常,由HTTP客戶端發起一個請求,建立一個到服務器指定端口(默認是80端口)的TCP連接。HTTP服務器則在那個端口監聽客戶端發送過來的請求。一旦收到請求,服務器(向客戶端)發回一個狀態行,比如"HTTP/1.1

200 OK",和(響應的)消息,消息的消息體可能是請求的文件、錯誤消息、或者其它一些信息。

HTTP使用TCP而不是UDP的原因在于(打開一個)一個網頁必須傳送很多數據,而TCP協議提供傳輸控制,按順序組織數據,和錯誤糾正。通過HTTP或者HTTPS協議請求的資源由統一資源標識符(Uniform Resource Identifiers,或者,更準確一些,URI)來標識。

客戶端與服務器端的結構與交互過程可以表示為下面2張圖:

圖1、Web客戶端-服務器端結構(其中web服務器的超文本鏈接,即通過網站上的一個鏈接跳轉到了其他服務器上)

圖2、Web客戶端與服務器端的交互

1.2、HTTP消息

客戶端與服務器之間的交互用到了兩種類型的消息:請求(Request)響應(Response)

HTTP請求的格式為:

圖3、HTTP請求的格式

HTTP響應的格式為:

圖4、HTTP響應的格式

從上面可以看出HTTP的請求和響應消息的首部均包含可變數量的字段,用一個空行(blank line)將所有首部字段(header)與消息主體(body)分隔開來。一個首部字段由字段名和隨后的冒號、一個空格和字段值組成,字段名不區分大小寫

報文頭可分為三類:一類應用于請求,一類應用于響應,還有一類描述主體。有一些報文頭(例如:Date)既可用于請求又可用于響應。描述主體的報文頭可以出現在POST請求和所有響應報文中。HTTP的首部字段如下圖所示:

圖5、HTTP首部字段

1.3、HTTP請求的方法

HTTP/1.1協議中共定義了八種方法(有時也叫“動作”)來表明Request-URI指定的資源的不同操作方式:

OPTIONS

返回服務器針對特定資源所支持的HTTP請求方法。也可以利用向Web服務器發送'*'的請求來測試服務器的功能性。

HEAD

向服務器索要與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應消息頭中的元信息。

GET

向特定的資源發出請求。注意:GET方法不應當被用于產生“副作用”的操作中,例如在Web Application中。其中一個原因是GET可能會被網絡蜘蛛等隨意訪問。

POST

向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。

PUT

向指定資源位置上傳其最新內容。

DELETE

請求服務器刪除Request-URI所標識的資源。

TRACE

回顯服務器收到的請求,主要用于測試或診斷。

CONNECT

HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。

方法名稱是區分大小寫的。當某個請求所針對的資源不支持對應的請求方法的時候,服務器應當返回狀態碼405(Method Not Allowed);當服務器不認識或者不支持對應的請求方法的時候,應當返回狀態碼501(Not Implemented)。

HTTP服務器至少應該實現GET和HEAD方法,其他方法都是可選的。此外,除了上述方法,特定的HTTP服務器還能夠擴展自定義的方法。

安全方法

開發者應當意識到他們的軟件代表了用戶在因特網上進行交互,并且應當告知用戶,他們正在進行的操作可能對他們自身或者其他人有未曾預料的重要影響。

特別地,對于GET和HEAD方法而言,除了進行獲取資源信息外,這些請求不應當再有任何其他意義。也就是說,這些方法應當被認為是“安全的”,即所謂安全的意味著該操作用于獲取信息而非修改信息。客戶端應當使用其他“非安全”方法,例如POST、PUT及DELETE來以特殊的方式(通常是按鈕而不是超鏈接)使得客戶能夠意識到可能要負的責任(例如一個按鈕帶來的資金交易)或者被告知正在請求的操作可能是不安全的(例如某個文件將被上傳或刪除)。

但是,不能想當然地認為服務器不會在處理某個GET請求時不會產生任何副作用。事實上,很多動態資源會把這作為其特性。這里重要的區別在于用戶并沒有請求這一副作用,因此不應由用戶為這些副作用承擔責任。

冪等方法

假如在不考慮諸如錯誤或者過期等問題的情況下,若干次請求的副作用與單次請求相同或者根本沒有副作用,那么這些請求方法就能夠被視作“冪等”的。GET,HEAD,PUT和DELETE方法都有這樣的冪等屬性,同樣由于根據協議,OPTIONS,TRACE都不應有副作用,因此也理所當然也是冪等的。

假如某個由若干個請求做成的請求串行產生的結果在重復執行這個請求串行或者其中任何一個或多個請求后仍沒有發生變化,則這個請求串行便是“冪等”

的。但是,可能出現若干個請求做成的請求串行是“非冪等”的,即使這個請求串行中所有執行的請求方法都是冪等的。例如,這個請求串行的結果依賴于某個會在下次執行這個串行的過程中被修改的變量。

1.4、HTTP響應的代碼

服務器程序響應的第一行叫狀態行。狀態行以HTTP版本號開始,后面跟著3位數字表示響應代碼,最后是易讀的響應短語。根據第一位可以把響應分成5類:

圖6、HTTP響應代碼

2、抓包分析

現在我們對HTTP基本上算是了解了,下面我用wireshark抓取打開博客園首頁時,我的電腦與博客園服務器的交互過程的HTTP數據包。做好準備工作,關閉一些可能干擾我們抓取打開博客園的相關程序。如下圖,我們在瀏覽器中輸入www.cnblogs.com并確定時,首先抓到如下包:

圖7、打開博客園抓取的包

從圖中可以看出,我們在瀏覽器中輸入www.cnblogs.com并確定時是向服務器發送了一個HTTP請求消息:GET? /? HTTP/1.1。根據1.2中介紹的HTTP消息的格式,我們知道GET對應request、/對應request-line、HTTP/1.1對應版本號。除了請求行之外,發送了一些首部字段,如:Accept、Accept-Language、User-Agent、Accept-Encoding、Host、Connection等。而且可以看出他們的格式就是:首部字段名: 字段值,注意冒號后面有個空格。

接下來我們看一下GET? /? HTTP/1.1請求的響應消息是怎樣的:

圖8、GET? /? HTTP/1.1請求的響應消息

響應消息的狀態行是:HTTP/1.1? 200? OK,其中HTTP/1.1對應版本號、200對應response-code、OK對應response-phrase。除了狀態行,還返回了一些首部字段,如:Cache-Control、Content-Type、Content-Encoding、Expires、Last-Modified、Vary、Server等等。(通過上圖我們可以看出,博客用的是IIS7.0)

上面抓的是GET的數據包,現在我來看一個POST的數據包——打開博客園首頁過程中獲取左邊的分類信息就是通過POST請求返回的。

圖9、POST數據包

我們可以看到,POST /ws/PublicUserService.asmx/GetLoginInfo HTTP/1.1。除了把GET換成了POST之外,其它信息差不多。下面我們放大看下發送的首部字段:

圖10、POST /ws/PublicUserService.asmx/GetLoginInfo HTTP/1.1的首部字段

NOTE:本節涉及的一些首部字段我就不在這里解釋了。我想,到了這里大家對HTTP的認識應該更深入了一步。

3、POST與GET的差異

1.3中介紹了8種方法,其中GET與POST最基本和常用了。表單提交中get和post方式的區別歸納如下幾點:

GET是從服務器上獲取數據,POST是向服務器傳送數據。

GET是把參數數據隊列加到提交表單的ACTION屬性所指的URL中,值和表單內各個字段一一對應,在URL中可以看到。POST是通過HTTP

POST機制,將表單內各個字段與其內容放置在HTML HEADER內一起傳送到ACTION屬性所指的URL地址。用戶看不到這個過程。

對于GET方式,服務器端用Request.QueryString獲取變量的值,對于POST方式,服務器端用Request.Form獲取提交的數據。

GET傳送的數據量較小,不能大于2KB(這主要是因為受URL長度限制)。POST傳送的數據量較大,一般被默認為不受限制。但理論上,限制取決于服務器的處理能力。

GET安全性較低,POST安全性較高。因為GET在傳輸過程,數據被放在請求的URL中,而如今現有的很多服務器、代理服務器或者用戶代理都會將請求URL記錄到日志文件中,然后放在某個地方,這樣就可能會有一些隱私的信息被第三方看到。另外,用戶也可以在瀏覽器上直接看到提交的數據,一些系統內部消息將會一同顯示在用戶面前。POST的所有操作對用戶來說都是不可見的。

在FORM提交的時候,如果不指定Method,則默認為GET請求(.net默認是POST),Form中提交的數據將會附加在url之后,以?分開與url分開。字母數字字符原樣發送,但空格轉換為“+”號,其它符號轉換為%XX,其中XX為該符號以16進制表示的ASCII(或ISO Latin-1)值。GET請求請提交的數據放置在HTTP請求協議頭中,而POST提交的數據則放在實體數據中;GET方式提交的數據最多只能有2048字節,而POST則沒有此限制。POST傳遞的參數在doc里,也就http協議所傳遞的文本,接受時再解析參數部分。獲得參數。一般用POST比較好。POST提交數據是隱式的,GET是通過在url里面傳遞的,用來傳遞一些不需要保密的數據,GET是通過在URL里傳遞參數,POST不是。

說明:關于“POST與GET的差異”查考了網上前輩的資料,由于找不出源頭,到處都是轉帖,這里就不貼出相關網址了,baidu或Google下就知道了。

4、以一個實例說明C#中如何使用POST、GET等操作

在介紹實例之前,我們要先介紹一下HttpWebRequest和HttpWebResponse,在C#中就是用這兩個類實現客戶端向服務器端發送HTTP消息、客戶端接受服務器端的HTTP響應。

4.1、HttpWebRequest

在設計實現實例之前我們首先要介紹一下HttpWebRequest這個類——提供WebRequest類的HTTP 特定的實現,HttpWebRequest類對WebRequest中定義的屬性和方法提供支持,也對使用戶能夠直接與使用 HTTP 的服務器交互的附加屬性和方法提供支持。

不要使用HttpWebRequest構造函數。使用System.Net.WebRequest.Create方法初始化新的HttpWebRequest對象。如果統一資源標識符 (URI) 的方案是http://或https://,則Create返回HttpWebRequest對象。

HTTP消息的首部字段(headers),在HttpWebRequest中表示為公開的屬性。下表列出了由屬性或方法設置或由系統設置的 HTTP 標頭。

如果本地計算機配置指定使用代理,或者如果請求指定代理,則使用代理發送請求。如果未指定代理,則請求發送到服務器。

HttpWebRequest類主要包括如下方法,用于與HTTP服務器交互:

Abort: 取消對 Internet 資源的請求。

AddRange: 向請求添加范圍標頭。

BeginGetRequestStream:開始對用來寫入數據的Stream對象的異步請求。

BeginGetResponse:開始對Internet 資源的異步請求。

Create:初始化新的WebRequest。(從WebRequest繼承。)

CreateDefault:為指定的 URI 方案初始化新的WebRequest實例。(從WebRequest繼承。)

CreateObjRef:創建一個對象,該對象包含生成用于與遠程對象進行通信的代理所需的全部相關信息。 (從MarshalByRefObject繼承。)

EndGetRequestStream:結束對用于寫入數據的Stream對象的異步請求。

EndGetResponse:結束對 Internet 資源的異步請求。

GetRequestStream:獲取用于寫入請求數據的Stream對象。

GetResponse:返回來自 Internet 資源的響應。

GetSystemWebProxy:返回當前模擬用戶的 Internet Explorer 設置中配置的代理。(從WebRequest繼承。)

InitializeLifetimeService:獲取控制此實例的生存期策略的生存期服務對象。 (從MarshalByRefObject繼承。)

RegisterPrefix:為指定的URI 注冊WebRequest子代。(從WebRequest繼承。)

4.2、HttpWebResponse

在設計實現實例之前我們還要介紹一下HttpWebRequest這個類——提供WebResponse類的HTTP 特定的實現。此類包含對WebResponse類中的屬性和方法的 HTTP 特定用法的支持。HttpWebResponse類用于生成發送HTTP請求和接收HTTP響應的HTTP獨立客戶端應用程序。

注意

不要混淆HttpWebResponseHttpResponse類;后者用于 ASP.NET 應用程序,而且它的方法和屬性是通過 ASP.NET 的內部Response對象公開的。

決不要直接創建HttpWebResponse類的實例。而應當使用通過調用HttpWebRequest.GetResponse所返回的實例。您必須調用Stream.Close方法或HttpWebResponse.Close方法來關閉響應并將連接釋放出來供重用。不必同時調用Stream.CloseHttpWebResponse.Close,但這樣做不會導致錯誤。

從 Internet 資源返回的公共標頭信息公開為該類的屬性。有關完整的列表,請參見下表。可以從Headers屬性以名稱/值對的形式讀取其他標頭。下表顯示可以通過HttpWebResponse類的屬性使用的公共 HTTP 標頭。

通過調用GetResponseStream方法,以Stream的形式返回來自 Internet 資源的響應的內容。

HttpWebRequest類主要包括如下方法與HTTP服務器交互:(與HttpWebRequest類相比,方法較少)

CreateObjRef:創建一個對象,該對象包含生成用于與遠程對象進行通信的代理所需的全部相關信息。(從MarshalByRefObject繼承。)

GetLifetimeService:檢索控制此實例的生存期策略的當前生存期服務對象。(從MarshalByRefObject繼承。)

GetResponseHeader:獲取與響應一起返回的標頭的內容。

GetResponseStream:獲取流,該流用于讀取來自服務器的響應的體。

InitializeLifetimeService:獲取控制此實例的生存期策略的生存期服務對象。(從MarshalByRefObject繼承。)

4.3、編寫WinForm程序打開博客園首頁(附源碼)

通過前面兩小節的介紹,我們對HttpWebRequest類和HttpWebRequest類有所了解,現在我們就應用它們來編寫一個小程序來實踐。程序界面大概如下:

功能也比較簡單,就是通過點擊“在WebBrowser中顯示”按鈕就在下方的 WebBrowser控件中顯示博客園首頁,通過點擊查看“html源碼”按鈕就彈出一個對話框顯示博客園首頁的html源碼。

首先我們介紹如何實現——通過點擊查看“html源碼”按鈕就彈出一個對話框顯示博客園首頁的html源碼。核心代碼如下:

通過點擊查看“html源碼”按鈕就彈出一個對話框顯示博客園首頁的html源碼

其實這個過程更我們通過在瀏覽器中輸入博客園網站打開效果是一樣的,只不過在這里我們是通過HttpWebRequest類和HttpWebRequest類的對象來實現的。

然而,通過點擊“在WebBrowser中顯示”按鈕就在下方的 WebBrowser控件中顯示博客園首頁的功能類似,只不過是在WebBrowser控件中顯示且我這里把一些常用的HTTP相關的操作封裝到一個命名空間Helper中,便于以后使用,本質跟上面的是一樣的。點擊下載整個項目的源碼。

我這個源碼還是比較簡陋,只是簡單地實現了使用HttpWebRequest類和HttpWebRequest類與HTTP服務器交互,更完善的功能期待你去完成。

補充說明:關于url的長度限制問題,IE的url最長可以傳 2083 字符(半角),而GET最多只能到2048字符。但是RFC 2616,Hypertext Transfer Protocol -- HTTP/1.1,并沒有對url的最大長度做限制。

參考:寫此文章時,我參閱了不少文章,我列舉其中印象比較深的

維基百科(HTTP),http://zh.wikipedia.org/zh-cn/HTTP

MSDN(HttpWebRequest),http://msdn.microsoft.com/zh-cn/library/8y7x3zz2%28v=VS.80%29.aspx

MSDN(HttpWebResponse),http://msdn.microsoft.com/zh-cn/library/system.net.httpwebresponse%28VS.80%29.aspx

TCP/IP協議詳解卷3

作者:吳秦

出處:http://www.cnblogs.com/skynet/

本文基于署名 2.5 中國大陸許可協議發布,歡迎轉載,演繹或用于商業目的,但是必須保留本文的署名吳秦(包含鏈接).

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,787評論 18 139
  • 一、概念(載錄于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436...
    yuantao123434閱讀 8,409評論 6 152
  • 本篇文章篇幅比較長,先來個思維導圖預覽一下。 一、概述 1.計算機網絡體系結構分層 2.TCP/IP 通信傳輸流 ...
    滌生_Woo閱讀 55,131評論 24 557
  • HTTP概述 超文本傳輸協議(HTTP,HyperText Transfer Protocol) 是互聯網上應用最...
    曹淵說創業閱讀 3,858評論 2 61
  • Http協議詳解 標簽(空格分隔): Linux 聲明:本片文章非原創,內容來源于博客園作者MIN飛翔的HTTP協...
    Sivin閱讀 5,245評論 3 82