引言
HTTP協(xié)議我想任何IT人士都耳熟能詳了撤蚊,大家都能說出個所以然來古掏。但是如果我問你HTTP協(xié)議的請求方法有哪些?POST與GET的差異侦啸?GET或POST傳送數(shù)據(jù)量的大小有限制嗎槽唾?HTTP響應的狀態(tài)有哪些?以及在C#中你如何使用光涂?如果你不能清楚地回答其中的大部分問題庞萍,那么這篇文章就是為你準備的!大綱如下:
1忘闻、HTTP概述
1.1钝计、HTTP協(xié)議的客戶端與服務(wù)器的交互
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協(xié)議的記憶或使你能夠?qū)TTP協(xié)議有所了解,首先簡單一下HTTP協(xié)議曹傀。超文本傳輸協(xié)議(HTTP辐脖,HyperText Transfer Protocol)是互聯(lián)網(wǎng)上應用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。所有的WWW文件都必須遵守這個標準皆愉。設(shè)計HTTP最初的目的是為了提供一種發(fā)布和接收HTML頁面的方法嗜价。
HTTP的發(fā)展是萬維網(wǎng)協(xié)會(World Wide Web Consortium)和Internet工作小組(Internet Engineering Task Force)合作的結(jié)果,(他們)最終發(fā)布了一系列的RFC幕庐,其中最著名的就是RFC 2616久锥。RFC 2616定義了HTTP協(xié)議中一個現(xiàn)今被廣泛使用的版本——HTTP 1.1。
1.1异剥、HTTP協(xié)議的客戶端與服務(wù)器的交互
HTTP是一個客戶端和服務(wù)器端請求和應答的標準(TCP)瑟由。客戶端是終端用戶,服務(wù)器端是網(wǎng)站冤寿。通過使用Web瀏覽器歹苦、網(wǎng)絡(luò)爬蟲或者其它的工具青伤,客戶端發(fā)起一個到服務(wù)器上指定端口(默認端口為80)的HTTP請求。(我們稱這個客戶端)調(diào)用戶代理(user agent)殴瘦。應答的服務(wù)器上存儲著(一些)資源狠角,比如HTML文件和圖像。(我們稱)這個應答服務(wù)器為源服務(wù)器(origin server)蚪腋。在用戶代理和源服務(wù)器中間可能存在多個中間層丰歌,比如代理,網(wǎng)關(guān)屉凯,或者隧道(tunnel)立帖。盡管TCP/IP協(xié)議是互聯(lián)網(wǎng)上最流行的應用,HTTP協(xié)議并沒有規(guī)定必須使用它和(基于)它支持的層神得。事實上厘惦,HTTP可以在任何其他互聯(lián)網(wǎng)協(xié)議上,或者在其他網(wǎng)絡(luò)上實現(xiàn)哩簿。HTTP只假定(其下層協(xié)議提供)可靠的傳輸宵蕉,任何能夠提供這種保證的協(xié)議都可以被其使用。
通常节榜,由HTTP客戶端發(fā)起一個請求羡玛,建立一個到服務(wù)器指定端口(默認是80端口)的TCP連接。HTTP服務(wù)器則在那個端口監(jiān)聽客戶端發(fā)送過來的請求宗苍。一旦收到請求稼稿,服務(wù)器(向客戶端)發(fā)回一個狀態(tài)行,比如"HTTP/1.1
200 OK"讳窟,和(響應的)消息让歼,消息的消息體可能是請求的文件、錯誤消息丽啡、或者其它一些信息谋右。
HTTP使用TCP而不是UDP的原因在于(打開一個)一個網(wǎng)頁必須傳送很多數(shù)據(jù),而TCP協(xié)議提供傳輸控制补箍,按順序組織數(shù)據(jù)改执,和錯誤糾正。通過HTTP或者HTTPS協(xié)議請求的資源由統(tǒng)一資源標識符(Uniform Resource Identifiers坑雅,或者辈挂,更準確一些,URI)來標識裹粤。
客戶端與服務(wù)器端的結(jié)構(gòu)與交互過程可以表示為下面2張圖:
圖1终蒂、Web客戶端-服務(wù)器端結(jié)構(gòu)(其中web服務(wù)器的超文本鏈接,即通過網(wǎng)站上的一個鏈接跳轉(zhuǎn)到了其他服務(wù)器上)
1.2后豫、HTTP消息
客戶端與服務(wù)器之間的交互用到了兩種類型的消息:請求(Request)和響應(Response)悉尾。
HTTP請求的格式為:
圖3、HTTP請求的格式
HTTP響應的格式為:
圖4挫酿、HTTP響應的格式
從上面可以看出HTTP的請求和響應消息的首部均包含可變數(shù)量的字段构眯,用一個空行(blank line)將所有首部字段(header)與消息主體(body)分隔開來。一個首部字段由字段名和隨后的冒號早龟、一個空格和字段值組成惫霸,字段名不區(qū)分大小寫。
報文頭可分為三類:一類應用于請求葱弟,一類應用于響應壹店,還有一類描述主體。有一些報文頭(例如:Date)既可用于請求又可用于響應芝加。描述主體的報文頭可以出現(xiàn)在POST請求和所有響應報文中硅卢。HTTP的首部字段如下圖所示:
圖5、HTTP首部字段
1.3藏杖、HTTP請求的方法
HTTP/1.1協(xié)議中共定義了八種方法(有時也叫“動作”)來表明Request-URI指定的資源的不同操作方式:
OPTIONS
返回服務(wù)器針對特定資源所支持的HTTP請求方法将塑。也可以利用向Web服務(wù)器發(fā)送'*'的請求來測試服務(wù)器的功能性。
HEAD
向服務(wù)器索要與GET請求相一致的響應蝌麸,只不過響應體將不會被返回点寥。這一方法可以在不必傳輸整個響應內(nèi)容的情況下,就可以獲取包含在響應消息頭中的元信息来吩。
GET
向特定的資源發(fā)出請求敢辩。注意:GET方法不應當被用于產(chǎn)生“副作用”的操作中,例如在Web Application中弟疆。其中一個原因是GET可能會被網(wǎng)絡(luò)蜘蛛等隨意訪問戚长。
POST
向指定資源提交數(shù)據(jù)進行處理請求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請求體中怠苔。POST請求可能會導致新的資源的建立和/或已有資源的修改同廉。
PUT
向指定資源位置上傳其最新內(nèi)容。
DELETE
請求服務(wù)器刪除Request-URI所標識的資源嘀略。
TRACE
回顯服務(wù)器收到的請求恤溶,主要用于測試或診斷乓诽。
CONNECT
HTTP/1.1協(xié)議中預留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器帜羊。
方法名稱是區(qū)分大小寫的。當某個請求所針對的資源不支持對應的請求方法的時候鸠天,服務(wù)器應當返回狀態(tài)碼405(Method Not Allowed)讼育;當服務(wù)器不認識或者不支持對應的請求方法的時候,應當返回狀態(tài)碼501(Not Implemented)。
HTTP服務(wù)器至少應該實現(xiàn)GET和HEAD方法奶段,其他方法都是可選的饥瓷。此外,除了上述方法痹籍,特定的HTTP服務(wù)器還能夠擴展自定義的方法呢铆。
安全方法
開發(fā)者應當意識到他們的軟件代表了用戶在因特網(wǎng)上進行交互,并且應當告知用戶蹲缠,他們正在進行的操作可能對他們自身或者其他人有未曾預料的重要影響棺克。
特別地,對于GET和HEAD方法而言线定,除了進行獲取資源信息外娜谊,這些請求不應當再有任何其他意義。也就是說斤讥,這些方法應當被認為是“安全的”纱皆,即所謂安全的意味著該操作用于獲取信息而非修改信息“派蹋客戶端應當使用其他“非安全”方法派草,例如POST、PUT及DELETE來以特殊的方式(通常是按鈕而不是超鏈接)使得客戶能夠意識到可能要負的責任(例如一個按鈕帶來的資金交易)或者被告知正在請求的操作可能是不安全的(例如某個文件將被上傳或刪除)蓉坎。
但是澳眷,不能想當然地認為服務(wù)器不會在處理某個GET請求時不會產(chǎn)生任何副作用。事實上蛉艾,很多動態(tài)資源會把這作為其特性钳踊。這里重要的區(qū)別在于用戶并沒有請求這一副作用,因此不應由用戶為這些副作用承擔責任勿侯。
冪等方法
假如在不考慮諸如錯誤或者過期等問題的情況下拓瞪,若干次請求的副作用與單次請求相同或者根本沒有副作用,那么這些請求方法就能夠被視作“冪等”的助琐。GET祭埂,HEAD,PUT和DELETE方法都有這樣的冪等屬性兵钮,同樣由于根據(jù)協(xié)議蛆橡,OPTIONS,TRACE都不應有副作用掘譬,因此也理所當然也是冪等的泰演。
假如某個由若干個請求做成的請求串行產(chǎn)生的結(jié)果在重復執(zhí)行這個請求串行或者其中任何一個或多個請求后仍沒有發(fā)生變化,則這個請求串行便是“冪等”
的葱轩。但是睦焕,可能出現(xiàn)若干個請求做成的請求串行是“非冪等”的藐握,即使這個請求串行中所有執(zhí)行的請求方法都是冪等的。例如垃喊,這個請求串行的結(jié)果依賴于某個會在下次執(zhí)行這個串行的過程中被修改的變量猾普。
1.4、HTTP響應的代碼
服務(wù)器程序響應的第一行叫狀態(tài)行本谜。狀態(tài)行以HTTP版本號開始初家,后面跟著3位數(shù)字表示響應代碼,最后是易讀的響應短語乌助。根據(jù)第一位可以把響應分成5類:
圖6笤成、HTTP響應代碼
2、抓包分析
現(xiàn)在我們對HTTP基本上算是了解了眷茁,下面我用wireshark抓取打開博客園首頁時炕泳,我的電腦與博客園服務(wù)器的交互過程的HTTP數(shù)據(jù)包。做好準備工作上祈,關(guān)閉一些可能干擾我們抓取打開博客園的相關(guān)程序培遵。如下圖,我們在瀏覽器中輸入www.cnblogs.com并確定時登刺,首先抓到如下包:
圖7籽腕、打開博客園抓取的包
從圖中可以看出,我們在瀏覽器中輸入www.cnblogs.com并確定時是向服務(wù)器發(fā)送了一個HTTP請求消息:GET? /? HTTP/1.1纸俭。根據(jù)1.2中介紹的HTTP消息的格式皇耗,我們知道GET對應request、/對應request-line揍很、HTTP/1.1對應版本號郎楼。除了請求行之外,發(fā)送了一些首部字段窒悔,如:Accept呜袁、Accept-Language、User-Agent简珠、Accept-Encoding阶界、Host、Connection等聋庵。而且可以看出他們的格式就是:首部字段名: 字段值膘融,注意冒號后面有個空格。
接下來我們看一下GET? /? HTTP/1.1請求的響應消息是怎樣的:
響應消息的狀態(tài)行是:HTTP/1.1? 200? OK氧映,其中HTTP/1.1對應版本號、200對應response-code攘宙、OK對應response-phrase屯耸。除了狀態(tài)行,還返回了一些首部字段蹭劈,如:Cache-Control疗绣、Content-Type、Content-Encoding铺韧、Expires多矮、Last-Modified、Vary哈打、Server等等塔逃。(通過上圖我們可以看出,博客用的是IIS7.0)
上面抓的是GET的數(shù)據(jù)包料仗,現(xiàn)在我來看一個POST的數(shù)據(jù)包——打開博客園首頁過程中獲取左邊的分類信息就是通過POST請求返回的湾盗。
圖9、POST數(shù)據(jù)包
我們可以看到立轧,POST /ws/PublicUserService.asmx/GetLoginInfo HTTP/1.1格粪。除了把GET換成了POST之外,其它信息差不多氛改。下面我們放大看下發(fā)送的首部字段:
圖10帐萎、POST /ws/PublicUserService.asmx/GetLoginInfo HTTP/1.1的首部字段
NOTE:本節(jié)涉及的一些首部字段我就不在這里解釋了。我想胜卤,到了這里大家對HTTP的認識應該更深入了一步疆导。
3、POST與GET的差異
1.3中介紹了8種方法葛躏,其中GET與POST最基本和常用了澈段。表單提交中g(shù)et和post方式的區(qū)別歸納如下幾點:
GET是從服務(wù)器上獲取數(shù)據(jù),POST是向服務(wù)器傳送數(shù)據(jù)舰攒。
GET是把參數(shù)數(shù)據(jù)隊列加到提交表單的ACTION屬性所指的URL中均蜜,值和表單內(nèi)各個字段一一對應,在URL中可以看到芒率。POST是通過HTTP
POST機制囤耳,將表單內(nèi)各個字段與其內(nèi)容放置在HTML HEADER內(nèi)一起傳送到ACTION屬性所指的URL地址。用戶看不到這個過程偶芍。
對于GET方式充择,服務(wù)器端用Request.QueryString獲取變量的值,對于POST方式匪蟀,服務(wù)器端用Request.Form獲取提交的數(shù)據(jù)椎麦。
GET傳送的數(shù)據(jù)量較小,不能大于2KB(這主要是因為受URL長度限制)材彪。POST傳送的數(shù)據(jù)量較大观挎,一般被默認為不受限制琴儿。但理論上,限制取決于服務(wù)器的處理能力嘁捷。
GET安全性較低造成,POST安全性較高。因為GET在傳輸過程雄嚣,數(shù)據(jù)被放在請求的URL中晒屎,而如今現(xiàn)有的很多服務(wù)器、代理服務(wù)器或者用戶代理都會將請求URL記錄到日志文件中缓升,然后放在某個地方鼓鲁,這樣就可能會有一些隱私的信息被第三方看到。另外港谊,用戶也可以在瀏覽器上直接看到提交的數(shù)據(jù)骇吭,一些系統(tǒng)內(nèi)部消息將會一同顯示在用戶面前。POST的所有操作對用戶來說都是不可見的歧寺。
在FORM提交的時候绵跷,如果不指定Method,則默認為GET請求(.net默認是POST)成福,F(xiàn)orm中提交的數(shù)據(jù)將會附加在url之后碾局,以?分開與url分開。字母數(shù)字字符原樣發(fā)送奴艾,但空格轉(zhuǎn)換為“+”號净当,其它符號轉(zhuǎn)換為%XX,其中XX為該符號以16進制表示的ASCII(或ISO Latin-1)值。GET請求請?zhí)峤坏臄?shù)據(jù)放置在HTTP請求協(xié)議頭中蕴潦,而POST提交的數(shù)據(jù)則放在實體數(shù)據(jù)中像啼;GET方式提交的數(shù)據(jù)最多只能有2048字節(jié),而POST則沒有此限制潭苞。POST傳遞的參數(shù)在doc里忽冻,也就http協(xié)議所傳遞的文本,接受時再解析參數(shù)部分此疹。獲得參數(shù)僧诚。一般用POST比較好。POST提交數(shù)據(jù)是隱式的蝗碎,GET是通過在url里面?zhèn)鬟f的湖笨,用來傳遞一些不需要保密的數(shù)據(jù),GET是通過在URL里傳遞參數(shù)蹦骑,POST不是慈省。
說明:關(guān)于“POST與GET的差異”查考了網(wǎng)上前輩的資料,由于找不出源頭眠菇,到處都是轉(zhuǎn)帖边败,這里就不貼出相關(guān)網(wǎng)址了袱衷,baidu或Google下就知道了。
4笑窜、以一個實例說明C#中如何使用POST致燥、GET等操作
在介紹實例之前,我們要先介紹一下HttpWebRequest和HttpWebResponse怖侦,在C#中就是用這兩個類實現(xiàn)客戶端向服務(wù)器端發(fā)送HTTP消息、客戶端接受服務(wù)器端的HTTP響應谜叹。
4.1匾寝、HttpWebRequest
在設(shè)計實現(xiàn)實例之前我們首先要介紹一下HttpWebRequest這個類——提供WebRequest類的HTTP 特定的實現(xiàn),HttpWebRequest類對WebRequest中定義的屬性和方法提供支持荷腊,也對使用戶能夠直接與使用 HTTP 的服務(wù)器交互的附加屬性和方法提供支持艳悔。
不要使用HttpWebRequest構(gòu)造函數(shù)。使用System.Net.WebRequest.Create方法初始化新的HttpWebRequest對象女仰。如果統(tǒng)一資源標識符 (URI) 的方案是http://或https://猜年,則Create返回HttpWebRequest對象。
HTTP消息的首部字段(headers)疾忍,在HttpWebRequest中表示為公開的屬性乔外。下表列出了由屬性或方法設(shè)置或由系統(tǒng)設(shè)置的 HTTP 標頭。
如果本地計算機配置指定使用代理一罩,或者如果請求指定代理杨幼,則使用代理發(fā)送請求。如果未指定代理聂渊,則請求發(fā)送到服務(wù)器差购。
HttpWebRequest類主要包括如下方法,用于與HTTP服務(wù)器交互:
Abort: 取消對 Internet 資源的請求汉嗽。
AddRange: 向請求添加范圍標頭欲逃。
BeginGetRequestStream:開始對用來寫入數(shù)據(jù)的Stream對象的異步請求。
BeginGetResponse:開始對Internet 資源的異步請求饼暑。
Create:初始化新的WebRequest稳析。(從WebRequest繼承。)
CreateDefault:為指定的 URI 方案初始化新的WebRequest實例弓叛。(從WebRequest繼承迈着。)
CreateObjRef:創(chuàng)建一個對象,該對象包含生成用于與遠程對象進行通信的代理所需的全部相關(guān)信息邪码。 (從MarshalByRefObject繼承裕菠。)
EndGetRequestStream:結(jié)束對用于寫入數(shù)據(jù)的Stream對象的異步請求。
EndGetResponse:結(jié)束對 Internet 資源的異步請求闭专。
GetRequestStream:獲取用于寫入請求數(shù)據(jù)的Stream對象奴潘。
GetResponse:返回來自 Internet 資源的響應旧烧。
GetSystemWebProxy:返回當前模擬用戶的 Internet Explorer 設(shè)置中配置的代理。(從WebRequest繼承画髓。)
InitializeLifetimeService:獲取控制此實例的生存期策略的生存期服務(wù)對象掘剪。 (從MarshalByRefObject繼承。)
RegisterPrefix:為指定的URI 注冊WebRequest子代奈虾。(從WebRequest繼承夺谁。)
4.2、HttpWebResponse
在設(shè)計實現(xiàn)實例之前我們還要介紹一下HttpWebRequest這個類——提供WebResponse類的HTTP 特定的實現(xiàn)肉微。此類包含對WebResponse類中的屬性和方法的 HTTP 特定用法的支持匾鸥。HttpWebResponse類用于生成發(fā)送HTTP請求和接收HTTP響應的HTTP獨立客戶端應用程序。
注意
不要混淆HttpWebResponse和HttpResponse類碉纳;后者用于 ASP.NET 應用程序勿负,而且它的方法和屬性是通過 ASP.NET 的內(nèi)部Response對象公開的。
決不要直接創(chuàng)建HttpWebResponse類的實例劳曹。而應當使用通過調(diào)用HttpWebRequest.GetResponse所返回的實例奴愉。您必須調(diào)用Stream.Close方法或HttpWebResponse.Close方法來關(guān)閉響應并將連接釋放出來供重用。不必同時調(diào)用Stream.Close和HttpWebResponse.Close铁孵,但這樣做不會導致錯誤锭硼。
從 Internet 資源返回的公共標頭信息公開為該類的屬性。有關(guān)完整的列表蜕劝,請參見下表账忘。可以從Headers屬性以名稱/值對的形式讀取其他標頭熙宇。下表顯示可以通過HttpWebResponse類的屬性使用的公共 HTTP 標頭鳖擒。
通過調(diào)用GetResponseStream方法,以Stream的形式返回來自 Internet 資源的響應的內(nèi)容烫止。
HttpWebRequest類主要包括如下方法與HTTP服務(wù)器交互:(與HttpWebRequest類相比蒋荚,方法較少)
CreateObjRef:創(chuàng)建一個對象,該對象包含生成用于與遠程對象進行通信的代理所需的全部相關(guān)信息馆蠕。(從MarshalByRefObject繼承期升。)
GetLifetimeService:檢索控制此實例的生存期策略的當前生存期服務(wù)對象。(從MarshalByRefObject繼承互躬。)
GetResponseHeader:獲取與響應一起返回的標頭的內(nèi)容播赁。
GetResponseStream:獲取流,該流用于讀取來自服務(wù)器的響應的體吼渡。
InitializeLifetimeService:獲取控制此實例的生存期策略的生存期服務(wù)對象容为。(從MarshalByRefObject繼承。)
4.3、編寫WinForm程序打開博客園首頁(附源碼)
通過前面兩小節(jié)的介紹坎背,我們對HttpWebRequest類和HttpWebRequest類有所了解替劈,現(xiàn)在我們就應用它們來編寫一個小程序來實踐。程序界面大概如下:
功能也比較簡單得滤,就是通過點擊“在WebBrowser中顯示”按鈕就在下方的 WebBrowser控件中顯示博客園首頁陨献,通過點擊查看“html源碼”按鈕就彈出一個對話框顯示博客園首頁的html源碼。
首先我們介紹如何實現(xiàn)——通過點擊查看“html源碼”按鈕就彈出一個對話框顯示博客園首頁的html源碼懂更。核心代碼如下:
通過點擊查看“html源碼”按鈕就彈出一個對話框顯示博客園首頁的html源碼
其實這個過程更我們通過在瀏覽器中輸入博客園網(wǎng)站打開效果是一樣的眨业,只不過在這里我們是通過HttpWebRequest類和HttpWebRequest類的對象來實現(xiàn)的。
然而沮协,通過點擊“在WebBrowser中顯示”按鈕就在下方的 WebBrowser控件中顯示博客園首頁的功能類似龄捡,只不過是在WebBrowser控件中顯示且我這里把一些常用的HTTP相關(guān)的操作封裝到一個命名空間Helper中,便于以后使用皂股,本質(zhì)跟上面的是一樣的墅茉。點擊下載整個項目的源碼命黔。
我這個源碼還是比較簡陋,只是簡單地實現(xiàn)了使用HttpWebRequest類和HttpWebRequest類與HTTP服務(wù)器交互,更完善的功能期待你去完成唁毒。
補充說明:關(guān)于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協(xié)議詳解卷3
作者:吳秦
出處:http://www.cnblogs.com/skynet/
本文基于署名 2.5 中國大陸許可協(xié)議發(fā)布隅忿,歡迎轉(zhuǎn)載心剥,演繹或用于商業(yè)目的,但是必須保留本文的署名吳秦(包含鏈接).