下面是學習借鑒的好文章:
HTTP Request header
HTTP協議詳解
關于HTTP協議,一篇就夠了
Http協議是實現不同端點間數據傳輸的重要協議,在了解httpClient首先要了解什么是http協議。 協議是指計算機通信網絡中兩臺計算機之間進行通信所必須共同遵守的規定或規則,超文本傳輸協議(HTTP)是一種通信協議,它允許將超文本標記語言(HTML)文檔從Web服務器傳送到客戶端的瀏覽器。
HTTP協議,即超文本傳輸協議(Hypertext transfer PRotocol)。是一種詳細規定了瀏覽器和萬維網(WWW = World Wide Web)服務器之間互相通信的規則,通過因特網傳送萬維網文檔的數據傳送協議。
HTTP協議是用于從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先于圖形)等。
HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型。HTTP是一個無狀態的協議。
在Internet中所有的傳輸都是通過TCP/ip進行的。HTTP協議作為TCP/IP模型中應用層的協議也不例外。HTTP協議通常承載于TCP協議之上,有時也承載于TLS或SSL協議層之上,這個時候,就成了我們常說的HTTPS。如下圖所示: 
HTTP默認的端口號為80,HTTPS的端口號為443。 瀏覽網頁是HTTP的主要應用,但是這并不代表HTTP就只能應用于網頁的瀏覽。HTTP是一種協議,只要通信的雙方都遵守這個協議,HTTP就能有用武之地。比如咱們常用的QQ,迅雷這些軟件,都會使用HTTP協議(還包括其他的協議)。 超文本傳輸協議(http協議)是實現超文本標記語言在網絡進行傳輸的平臺,超文本標記語言(Hyper Text Mart-up Language ,簡稱HTML)是WWW的描述語言,由Tim Berners-lee提出。目的是為了能把存放在一臺電腦中的文本或圖形與另一臺電腦中的文本或圖形方便地聯系在一起,形成有機的整體,人們不用考慮具體信息是在當前電腦上還是在網絡的其它電腦上。這樣,你只要使用鼠標在某一文檔中點取一個圖標,Internet就會馬上轉到與此圖標相關的內容上去,而這些信息可能存放在網絡的另一臺電腦中。這樣可以有效實現資源共享,形成一個有機整體。而httpclient則是http協議的具體實現,通過httpclient可以實現不同端點之間數據的傳輸,現在.net中http和webapi進行搭配實現跨平臺調用數據,也可以用httpclient來爬取數據等等。 **
當我們打開瀏覽器,在地址欄中輸入URL,然后我們就看到了網頁。 實際上我們輸入URL后,我們的瀏覽器給Web服務器發送了一個Request, Web服務器接到Request后進行處理,生成相應的Response,然后發送給瀏覽器, 瀏覽器解析Response中的HTML,這樣我們就看到了網頁 詳細流程如下:
1、瀏覽器向 DNS 服務器請求解析該 URL 中的域名所對應的 IP 地址;
2、解析出 IP 地址后,根據該 IP 地址和默認端口 80,和服務器建立TCP連接;
3、瀏覽器發出讀取文件(URL 中域名后面部分對應的文件)的HTTP 請求,該請求報文作為 TCP 三次握手的第三個報文的數據發送給服務器;
4、服務器對瀏覽器請求作出響應,并把對應的 html 文本發送給瀏覽器;
5、釋放 TCP連接;
6、瀏覽器將該 html 文本并顯示內容;
每當輸入一個url都會生成一個http請求,每個http請求的結構如下: 先看Request 消息的結構, Request 消息分為3部分,第一部分叫Request line, 第二部分叫Request header, 第三部分是body. header和body之間有個空行, 結構如下圖

第一行中的Method表示請求方法,比如”POST”,”GET”, Path-to-resoure表示請求的資源, Http/version-number 表示HTTP協議的版本號
當使用的是”GET” 方法的時候, body是為空的
比如我們打開博客園首頁的request 如下
GET http://www.cnblogs.com/ HTTP/1.1 Host: www.cnblogs.com 抽象的東西,難以理解,老感覺是虛的, 所謂眼見為實, 實際見到的東西,我們才能理解和記憶。 我們今天用Fiddler,實際的看看Request和Response.
下面我們打開Fiddler 捕捉一個博客園登錄的Request 然后分析下它的結構, 在Inspectors tab下以Raw的方式可以看到完整的Request的消息,   如下圖: 
我們再看Response消息的結構, 和Request消息的結構基本一樣。 同樣也分為三部分,第一部分叫Response line, 第二部分叫Response header,第三部分是body. header和body之間也有個空行,  結構如下圖: 
HTTP/version-number表示HTTP協議的版本號, status-code 和message 請看下節[狀態代碼]的詳細解釋.
我們用Fiddler 捕捉一個博客園首頁的Response然后分析下它的結構, 在Inspectors tab下以Raw的方式可以看到完整的Response的消息,   如下圖: 
Get和Post方法的區別 Http協議定義了很多與服務器交互的方法,最基本的有4種,分別是GET,POST,PUT,DELETE. 一個URL地址用于描述一個網絡上的資源,而HTTP中的GET, POST, PUT, DELETE就對應著對這個資源的查,改,增,刪4個操作。 我們最常見的就是GET和POST了。GET一般用于獲取/查詢資源信息,而POST一般用于更新資源信息.
我們看看GET和POST的區別
GET提交的數據會放在URL之后,以?分割URL和傳輸數據,參數之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的數據放在HTTP包的Body中.
GET提交的數據大小有限制(因為瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.
GET方式需要使用Request.QueryString來取得變量的值,而POST方式通過Request.Form來獲取變量的值。
GET方式提交數據,會帶來安全問題,比如一個登錄頁面,通過GET方式提交數據時,用戶名和密碼將出現在URL上,如果頁面可以被緩存或者其他人可以訪問這臺機器,就可以從歷史記錄獲得該用戶的賬號和密碼.
狀態碼 Response 消息中的第一行叫做狀態行,由HTTP協議版本號, 狀態碼, 狀態消息 三部分組成。
狀態碼用來告訴HTTP客戶端,HTTP服務器是否產生了預期的Response.
HTTP/1.1中定義了5類狀態碼, 狀態碼由三位數字組成,第一個數字定義了響應的類別
1XX 提示信息 - 表示請求已被成功接收,繼續處理
2XX 成功 - 表示請求已被成功接收,理解,接受
3XX 重定向 - 要完成請求必須進行更進一步的處理
4XX 客戶端錯誤 - 請求有語法錯誤或請求無法實現
5XX 服務器端錯誤 - 服務器未能實現合法的請求
看看一些常見的狀態碼
200 OK
最常見的就是成功響應狀態碼200了, 這表明該請求被成功地完成,所請求的資源發送回客戶端
如下圖, 打開博客園首頁: 
302 Found
重定向,新的URL會在response 中的Location中返回,瀏覽器將會自動使用新的URL發出新的Request
例如在IE中輸入, http://www.google.com. HTTP服務器會返回302, IE取到Response中Location header的新URL, 又重新發送了一個Request. 
304 Not Modified
代表上次的文檔已經被緩存了, 還可以繼續使用,
例如打開博客園首頁, 發現很多Response 的status code 都是304 
提示: 如果你不想使用本地緩存可以用Ctrl+F5 強制刷新頁面
400 Bad Request 客戶端請求與語法錯誤,不能被服務器所理解
403 Forbidden 服務器收到請求,但是拒絕提供服務
404 Not Found
請求資源不存在(輸錯了URL)
比如在IE中輸入一個錯誤的URL, http://www.cnblogs.com/tesdf.aspx 
拓展:
URL詳解 URL(Uniform Resource Locator) 地址用于描述一個網絡上的資源, 基本格式如下
schema://host[:port#]/path/…/[?query-string][#anchor] scheme 指定低層使用的協議(例如:http, https, ftp)
host HTTP服務器的IP地址或者域名
port# HTTP服務器的默認端口是80,這種情況下端口號可以省略。如果使用了別的端口,必須指明,例如 http://www.cnblogs.com:8080/
path 訪問資源的路徑
query-string 發送給http服務器的數據
anchor- 錨
URL 的一個例子
http://www.mywebsite.com/sj/test/test.aspx?name=sviergn&x=true#stuff
Schema: http host: www.mywebsite.com path: /sj/test/test.aspx Query String: name=sviergn&x=true Anchor: stuff
IpAddress DNS IPHostEntity 描述(需要再次學習) dns可以將域名實例化成為相應的ip地址,實例化dns類有兩種方式分別是調用resolve()和GetHostByAddress通過傳入url和ip來實例化dns,iphostentity封裝了與某個特定主機的信息,
HTTP常見的請求頭(在HTTP/1.1 協議中,所有的請求頭,除Host外,都是可選的) If-None-Match:If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 當用戶再次請求該資源時,將在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服務器驗證資源的ETag沒有改變(該資源沒有更新),將返回一個304狀態告訴客戶端使用本地緩存文件。否則將返回200狀態和新的資源和Etag. 使用這樣的機制將提高網站的性能。例如: If-None-Match: “03f2b33c0bfcc1:0”。 If-Modified-Since:把瀏覽器端緩存頁面的最后修改時間發送到服務器去,服務器會把這個時間與服務器上實際文件的最后修改時間進行對比。如果時間一致,那么返回304,客戶端就直接使用本地緩存文件。如果時間不一致,就會返回200和新的文件內容。客戶端接到之后,會丟棄舊文件,把新文件緩存起來,并顯示在瀏覽器中。 Pragma:指定“no-cache”值表示服務器必須返回一個刷新后的文檔,即使它是代理服務器而且已經有了頁面的本地拷貝;在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一樣。Pargma只有一個用法, 例如: Pragma: no-cache 注意: 在HTTP/1.0版本中,只實現了Pragema:no-cache, 沒有實現Cache-Control
Cache-Control:指定請求和響應遵循的緩存機制。緩存指令是單向的(響應中出現的緩存指令在請求中未必會出現),且是獨立的(在請求消息或響應消息中設置Cache-Control并不會修改另一個消息處理過程中的緩存處理過程)。請求時的緩存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,響應消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage。
Cache-Control:Public 可以被任何緩存所緩存 Cache-Control:Private 內容只緩存到私有緩存中 Cache-Control:no-cache 所有內容都不會被緩存 Cache-Control:no-store 用于防止重要的信息被無意的發布。在請求消息中發送將使得請求和響應消息都不使用緩存。 Cache-Control:max-age 指示客戶機可以接收生存期不大于指定時間(以秒為單位)的響應。 Cache-Control:min-fresh 指示客戶機可以接收響應時間小于當前時間加上指定時間的響應。 Cache-Control:max-stale 指示客戶機可以接收超出超時期間的響應消息。如果指定max-stale消息的值,那么客戶機可以接收超出超時期指定值之內的響應消息。
Accept:瀏覽器端可以接受的MIME類型。例如:Accept: text/html 代表瀏覽器可以接受服務器回發的類型為 text/html 也就是我們常說的html文檔,如果服務器無法返回text/html類型的數據,服務器應該返回一個406錯誤(non acceptable)。通配符 * 代表任意類型,例如 Accept: / 代表瀏覽器可以處理所有類型,(一般瀏覽器發給服務器都是發這個)。
Accept-Encoding:瀏覽器申明自己可接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法(gzip,deflate);Servlet能夠向支持gzip的瀏覽器返回經gzip編碼的HTML頁面。許多情形下這可以減少5到10倍的下載時間。例如: Accept-Encoding: gzip, deflate。如果請求消息中沒有設置這個域,服務器假定客戶端對各種內容編碼都可以接受。
Accept-Language:瀏覽器申明自己接收的語言。語言跟字符集的區別:中文是語言,中文有多種字符集,比如big5,gb2312,gbk等等;例如:Accept-Language: en-us。如果請求消息中沒有設置這個報頭域,服務器假定客戶端對各種語言都可以接受。
Accept-Charset:瀏覽器可接受的字符集。如果在請求消息中沒有設置這個域,缺省表示任何字符集都可以接受。
User-Agent:告訴HTTP服務器,客戶端使用的操作系統和瀏覽器的名稱和版本。 例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)。
Content-Type:例如:Content-Type: application/x-www-form-urlencoded。
Referer:包含一個URL,用戶從該URL代表的頁面出發訪問當前請求的頁面。提供了Request的上下文信息的服務器,告訴服務器我是從哪個鏈接過來的,比如從我主頁上鏈接到一個朋友那里,他的服務器就能夠從HTTP Referer中統計出每天有多少用戶點擊我主頁上的鏈接訪問他的網站。 例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
Connection: 例如:Connection: keep-alive 當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。HTTP 1.1默認進行持久連接。利用持久連接的優點,當頁面包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點,Servlet需要在應答中發送一個Content-Length頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,然后在正式寫出內容之前計算它的大小。 Connection: close 代表一個Request完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接會關閉,當客戶端再次發送Request,需要重新建立TCP連接。
Host:(發送請求時,該頭域是必需的)主要用于指定被請求資源的Internet主機和端口號,它通常從HTTP URL中提取出來的。HTTP/1.1請求必須包含主機頭域,否則系統會以400狀態碼返回。 例如: 我們在瀏覽器中輸入:http://www.guet.edu.cn/index.html,瀏覽器發送的請求消息中,就會包含Host請求頭域:Host:http://www.guet.edu.cn,此處使用缺省端口號80,若指定了端口號,則變成:Host:指定端口號。
Cookie:最重要的請求頭之一, 將cookie的值發送給HTTP服務器。
Content-Length:表示請求消息正文的長度。例如:Content-Length: 38。
Authorization:授權信息,通常出現在對服務器發送的WWW-Authenticate頭的應答中。主要用于證明客戶端有權查看某個資源。當瀏覽器訪問一個頁面時,如果收到服務器的響應代碼為401(未授權),可以發送一個包含Authorization請求報頭域的請求,要求服務器對其進行驗證。
UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE瀏覽器所發送的非標準的請求頭,表示屏幕大小、顏色深度、操作系統和CPU類型。
From:請求發送者的email地址,由一些特殊的Web客戶程序使用,瀏覽器不會用到它。
Range:可以請求實體的一個或者多個子范圍。例如, 表示頭500個字節:bytes=0-499 表示第二個500字節:bytes=500-999 表示最后500個字節:bytes=-500 表示500字節以后的范圍:bytes=500- 第一個和最后一個字節:bytes=0-0,-1 同時指定幾個范圍:bytes=500-600,601-999 但是服務器可以忽略此請求頭,如果無條件GET包含Range請求頭,響應會以狀態碼206(PartialContent)返回而不是以200(OK)。
HTTP常見的響應頭
Allow:服務器支持哪些請求方法(如GET、POST等)。
Date:表示消息發送的時間,時間的描述格式由rfc822定義。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的時間表示世界標準時,換算成本地時間,需要知道用戶所在的時區。你可以用setDateHeader來設置這個頭以避免轉換時間格式的麻煩
Expires:指明應該在什么時候認為文檔已經過期,從而不再緩存它,重新從服務器獲取,會更新緩存。過期之前使用本地緩存。HTTP1.1的客戶端和緩存會將非法的日期格式(包括0)看作已經過期。eg:為了讓瀏覽器不要緩存頁面,我們也可以將Expires實體報頭域,設置為0。 例如: Expires: Tue, 08 Feb 2022 11:35:14 GMT
P3P:用于跨域設置Cookie, 這樣可以解決iframe跨域訪問cookie的問題 例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR
Set-Cookie:非常重要的header, 用于把cookie發送到客戶端瀏覽器,每一個寫入cookie都會生成一個Set-Cookie。 例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com
ETag:和If-None-Match 配合使用。
Last-Modified:用于指示資源的最后修改日期和時間。Last-Modified也可用setDateHeader方法來設置。
Content-Type:WEB服務器告訴瀏覽器自己響應的對象的類型和字符集。Servlet默認為text/plain,但通常需要顯式地指定為text/html。由于經常要設置Content-Type,因此HttpServletResponse提供了一個專用的方法setContentType。可在web.xml文件中配置擴展名和MIME類型的對應關系。 例如:Content-Type: text/html;charset=utf-8 Content-Type:text/html;charset=GB2312 Content-Type: image/jpeg
媒體類型的格式為:大類/小類,比如text/html。 IANA(The Internet Assigned Numbers Authority,互聯網數字分配機構)定義了8個大類的媒體類型,分別是: application— (比如: application/vnd.ms-Excel.) audio (比如: audio/mpeg.) image (比如: image/png.) message (比如,:message/http.) model(比如:model/vrml.) multipart (比如:multipart/form-data.) text(比如:text/html.) video(比如:video/quicktime.)
Content-Range:用于指定整個實體中的一部分的插入位置,他也指示了整個實體的長度。在服務器向客戶返回一個部分響應,它必須描述響應覆蓋的范圍和整個實體長度。一般格式:Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-length。 例如,傳送頭500個字節次字段的形式:Content-Range:bytes0-499/1234如果一個http消息包含此節(例如,對范圍請求的響 應或對一系列范圍的重疊請求),Content-Range表示傳送的范圍。
Content-Length:指明實體正文的長度,以字節方式存儲的十進制數字來表示。在數據下行的過程中,Content-Length的方式要預先在服務器中緩存所有數據,然后所有數據再一股腦兒地發給客戶端。只有當瀏覽器使用持久HTTP連接時才需要這個數據。如果你想要利用持久連接的優勢,可以把輸出文檔寫入ByteArrayOutputStram,完成后查看其大小,然后把該值放入Content-Length頭,最后通過byteArrayStream.writeTo(response.getOutputStream()發送內容。 例如: Content-Length: 19847
Content-Encoding:WEB服務器表明自己使用了什么壓縮方法(gzip,deflate)壓縮響應中的對象。只有在解碼之后才可以得到Content-Type頭指定的內容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時間。java的GZIPOutputStream可以很方便地進行gzip壓縮,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet應該通過查看Accept-Encoding頭(即request.getHeader(“Accept-Encoding”))檢查瀏覽器是否支持gzip,為支持gzip的瀏覽器返回經gzip壓縮的HTML頁面,為其他瀏覽器返回普通頁面。 例如:Content-Encoding:gzip
Content-Language:WEB服務器告訴瀏覽器自己響應的對象所用的自然語言。例如: Content-Language:da。沒有設置該域則認為實體內容將提供給所有的語言閱讀。
Server:指明HTTP服務器用來處理請求的軟件信息。例如:Server: Microsoft-IIS/7.5、Server:Apache-Coyote/1.1。此域能包含多個產品標識和注釋,產品標識一般按照重要性排序。
X-AspNet-Version:如果網站是用asp.net開發的,這個header用來表示ASP.NET的版本。 例如: X-AspNet-Version: 4.0.30319
X-Powered-By:表示網站是用什么技術開發的。 例如: X-Powered-By: ASP.NET
Connection: 例如:Connection: keep-alive 當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。 Connection: close 代表一個Request完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接會關閉,當客戶端再次發送Request,需要重新建立TCP連接。
Location:用于重定向一個新的位置,包含新的URL地址。表示客戶應當到哪里去提取文檔。Location通常不是直接設置的,而是通過HttpServletResponse的sendRedirect方法,該方法同時設置狀態代碼為302。Location響應報頭域常用在更換域名的時候。
Refresh:表示瀏覽器應該在多少時間之后刷新文檔,以秒計。除了刷新當前文檔之外,你還可以通過setHeader(“Refresh”, “5; URL=http://host/path“)讓瀏覽器讀取指定的頁面。注意這種功能通常是通過設置HTML頁面HEAD區的http://host/path“>實現,這是因為,自動刷新或重定向對于那些不能使用CGI或Servlet的HTML編寫者十分重要。但是,對于Servlet來說,直接設置Refresh頭更加方便。注意Refresh的意義是“N秒之后刷新本頁面或訪問指定頁面”,而不是“每隔N秒刷新本頁面或訪問指定頁面”。因此,連續刷新要求每次都發送一個Refresh頭,而發送204狀態代碼則可以阻止瀏覽器繼續刷新,不管是使用Refresh頭還是
新聞熱點
疑難解答