1. 程式人生 > >一次完整的HTTP請求所經歷的7個步驟

一次完整的HTTP請求所經歷的7個步驟

1. 建立TCP連線
在HTTP工作開始之前,Web瀏覽器首先要通過網路與Web伺服器建立連線,該連線是通過TCP來完成的,該協議與IP協議共同構建Internet,即著名的TCP/IP協議族,因此Internet又被稱作是TCP/IP網路。HTTP是比TCP更高層次的應用層協議,根據規則,只有低層協議建立之後才能進行更高層協議的連線,因此,首先要建立TCP連線,一般TCP連線的埠號是80。

2. Web瀏覽器向Web伺服器傳送請求命令 
一旦建立了TCP連線,Web瀏覽器就會向Web伺服器傳送請求命令。例如:GET/sample/hello.jsp HTTP/1.1。

3. Web瀏覽器傳送請求頭資訊

 
瀏覽器傳送其請求命令之後,還要以頭資訊的形式向Web伺服器傳送一些別的資訊,之後瀏覽器傳送了一空白行來通知伺服器,它已經結束了該頭資訊的傳送。

4. Web伺服器應答 
客戶機向伺服器發出請求後,伺服器會客戶機回送應答, HTTP/1.1 200 OK ,應答的第一部分是協議的版本號和應答狀態碼。

5. Web伺服器傳送應答頭資訊 
正如客戶端會隨同請求傳送關於自身的資訊一樣,伺服器也會隨同應答向用戶傳送關於它自己的資料及被請求的文件。

6. Web伺服器向瀏覽器傳送資料 
Web伺服器向瀏覽器傳送頭資訊後,它會發送一個空白行來表示頭資訊的傳送到此為結束,接著,它就以Content-Type應答頭資訊所描述的格式傳送使用者所請求的實際資料。

7. Web伺服器關閉TCP連線 
一般情況下,一旦Web伺服器向瀏覽器傳送了請求資料,它就要關閉TCP連線,然後如果瀏覽器或者伺服器在其頭資訊加入了這行程式碼:Connection:keep-alive

TCP連線在傳送後將仍然保持開啟狀態,於是,瀏覽器可以繼續通過相同的連線傳送請求。保持連線節省了為每個請求建立新連線所需的時間,還節約了網路頻寬。

TCP通過三次握手建立可靠連線,此篇文章對此不做多贅述,這裡主要簡單講講客戶端在發起HTTP請求的時候,傳送的資料包裡面有什麼資料,以及請求成功接收WEB伺服器的資料包;

這裡通過Fiddler工具抓取手機APP向WEB伺服器傳送的資料包:

技術分享

HTTP請求為http://xg.mediportal.com.cn/health/sms/verify/telephone

當瀏覽器向Web伺服器發出請求時,它向伺服器傳遞了一個數據塊,也就是請求資訊,

HTTP請求資訊由3部分組成

1、請求方法(GET/POST)、URI、協議/版本

2、請求頭(Request Header)

3、請求正文

以上圖做例進行分析:

POST http://xg.mediportal.com.cn/health/sms/verify/telephone HTTP/1.1

User-Agent: DGroupPatient/1.052701.230/Dalvik/2.1.0 (Linux; U; Android 5.1.1; KIW-AL10 Build/HONORKIW-AL10)
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: xg.mediportal.com.cn
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 33

telephone=15527177736&userType=1&

1)請求方法、URI、協議/版本

請求的第一行是“方法、URL、協議/版本”:

POST http://xg.mediportal.com.cn/health/sms/verify/telephone HTTP/1.1

以上程式碼中“POST”代表請求方法,“http://xg.mediportal.com.cn/health/sms/verify/telephone”表示URI,“HTTP/1.1代表協議和協議的版本。

根據HTTP標準,HTTP請求可以使用多種請求方法。例如:HTTP1.1目前支援7種請求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。

GET

請求獲取由Request-URI所標識的資源

POST

在Request-URI所標識的資源後附加新的資料

HEAD

請求獲取由Request-URI所標識的資源的響應訊息報頭

OPTIONS

請求查詢伺服器的效能,或查詢與資源相關的選項和需求

PUT

請求伺服器儲存一個資源,並用Request-URI作為其標識

DELETE

請求伺服器刪除由Request-URI所標識的資源

TRACE

請求伺服器回送收到的請求資訊,主要用語測試或診斷

Internet應用中,最常用的方法是GET和POST。最後,協議版本聲明瞭通訊過程中使用HTTP的版本。

2)請求頭(Request Header)

請求頭包含許多有關的客戶端環境和請求正文的有用資訊。例如,請求頭可以宣告瀏覽器所用的語言,請求正文的長度等。

User-Agent: DGroupPatient/1.052701.230/Dalvik/2.1.0 (Linux; U; Android 5.1.1; KIW-AL10 Build/HONORKIW-AL10)   //使用者傳送請求的客戶端環境
Content-Type: application/x-www-form-urlencoded; charset=UTF-8   //表單預設的提交資料的格式
Host: xg.mediportal.com.cn   //請求資源的Intenet主機和埠號
Connection: Keep-Alive   //持久連線
Accept-Encoding: gzip   //瀏覽器能夠進行解碼的資料編碼方式
Content-Length: 33   //請求正文的長度

Content-Type

是返回訊息中非常重要的內容,表示後面的文件屬於什麼MIME型別。Content-Type: [type]/[subtype]; parameter。例如最常見的就是text/html,它的意思是說返回的內容是文字型別,這個文字又是HTML格式的。原則上瀏覽器會根據Content-Type來決定如何顯示返回的訊息體內容

Host

指定請求資源的Intenet主機和埠號,必須表示請求url的原始伺服器或閘道器的位置。HTTP/1.1請求必須包含主機頭域,否則系統會以400狀態碼返回

Accept

瀏覽器可接受的MIME型別

Accept-Charset

瀏覽器可接受的字符集

Accept-Encoding

瀏覽器能夠進行解碼的資料編碼方式,比如gzip。Servlet能夠向支援gzip的瀏覽器返回經gzip編碼的HTML頁面。許多情形下這可以減少5到10倍的下載時間

Accept-Language

瀏覽器所希望的語言種類,當伺服器能夠提供一種以上的語言版本時要用到

Authorization

授權資訊,通常出現在對伺服器傳送的WWW-Authenticate頭的應答中

Connection

表示是否需要持久連線。如果Servlet看到這裡的值為“Keep- Alive”,或者看到請求使用的是HTTP1.1(HTTP 1.1預設進行持久連線),它就可以利用持久連線的優點,當頁面包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點,Servlet需要在應答中傳送一個Content-Length頭,最簡單的實現方法是:先把內容寫入 ByteArrayOutputStream,然後在正式寫出內容之前計算它的大小

Content-Length

表示請求訊息正文的長度

Cookie

這是最重要的請求頭資訊之一

From

請求傳送者的email地址,由一些特殊的Web客戶程式使用,瀏覽器不會用到它

Host

初始URL中的主機和埠

If-Modified-Since

只有當所請求的內容在指定的日期之後又經過修改才返回它,否則返回304“Not Modified”應答

Pragma

指定“no-cache”值表示伺服器必須返回一個重新整理後的文件,即使它是代理伺服器而且已經有了頁面的本地拷貝

Referer

包含一個URL,使用者從該URL代表的頁面出發訪問當前請求的頁面

User-Agent

瀏覽器型別,如果Servlet返回的內容與瀏覽器型別有關則該值非常有用

UA-Pixels,UA-Color,UA-OS,UA-CPU

由某些版本的IE瀏覽器所傳送的非標準的請求頭,表示螢幕大小、顏色深度、作業系統和CPU型別

 常見的MIME型別如下:

  •     text/html : HTML格式
  •     text/plain :純文字格式      
  •     text/xml :  XML格式
  •     image/gif :gif圖片格式    
  •     image/jpeg :jpg圖片格式 
  •     image/png:png圖片格式

    以application開頭的媒體格式型別:

  •    application/xhtml+xml :XHTML格式
  •    application/xml     : XML資料格式
  •    application/atom+xml  :Atom XML聚合格式    
  •    application/json    : JSON資料格式
  •    application/pdf       :pdf格式  
  •    application/msword  : Word文件格式
  •    application/octet-stream : 二進位制流資料(如常見的檔案下載)
  •    application/x-www-form-urlencoded : <form encType=””>中預設的encType,form表單資料被編碼為key/value格式傳送到伺服器(表單預設的提交資料的格式)

   另外一種常見的媒體格式是上傳檔案之時使用的:

  •     multipart/form-data : 需要在表單中進行檔案上傳時,就需要使用該格式

3)請求正文

請求頭和請求正文之間是一個空行,這個行非常重要,它表示請求頭已經結束,接下來的是請求正文。請求正文中可以包含客戶提交的查詢字串資訊:

telephone=15527177736&userType=1&

http響應格式

HTTP應答與HTTP請求相似,HTTP響應也由3個部分構成,分別是:

1、狀態行

2、響應頭(Response Header)

3、響應正文

HTTP/1.1 200 OK   //狀態行
Server: nginx
Date: Tue, 31 May 2016 02:09:24 GMT
Content-Type: application/json;charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With,access_token,access-token,content-type,multipart/form-data,application/x-www-form-urlencoded
Access-Control-Allow-Methods: GET,POST,OPTIONS
Content-Length: 49

{"resultCode":1,"resultMsg":"手機號未註冊"}   //正文

(1)狀態行

由協議版本、數字形式的狀態程式碼、及相應的狀態描述,各元素之間以空格分隔。

狀態程式碼:

狀態程式碼由3位數字組成,表示請求是否被理解或被滿足。

狀態描述:

狀態描述給出了關於狀態程式碼的簡短的文字描述。

狀態程式碼的第一個數字定義了響應的類別,後面兩位沒有具體的分類。

第一個數字有五種可能的取值:

- 1xx:   指示資訊—表示請求已接收,繼續處理。

- 2xx:   成功—表示請求已經被成功接收、理解、接受。

- 3xx:   重定向—要完成請求必須進行更進一步的操作。

- 4xx:   客戶端錯誤—請求有語法錯誤或請求無法實現。

- 5xx: 伺服器端錯誤—伺服器未能實現合法的請求。

狀態程式碼 狀態描述    說明

   200  OK    客戶端請求成功

   400  Bad Request   由於客戶端請求有語法錯誤,不能被伺服器所理解。

   401  Unauthonzed   請求未經授權。這個狀態程式碼必須和WWW-Authenticate報頭域一起使用

   403   Forbidden   伺服器收到請求,但是拒絕提供服務。伺服器通常會在響應正文中給出不提供服務的原因

   404   Not Found   請求的資源不存在,例如,輸入了錯誤的URL。

   500  Internal Server Error 伺服器發生不可預期的錯誤,導致無法完成客戶端的請求。

  503  Service Unavailable   伺服器當前不能夠處理客戶端的請求,在一段時間之後,伺服器可能會恢復正常

(2)響應頭

響應頭可能包括:

Location:

Location響應報頭域用於重定向接受者到一個新的位置。例如:客戶端所請求的頁面已不存在原先的位置,為了讓客戶端重定向到這個頁面新的位置,服務 器端可以發回Location響應報頭後使用重定向語句,讓客戶端去訪問新的域名所對應的伺服器上的資源。當我們在JSP中使用重定向語句的時候,伺服器 端向客戶端發回的響應報頭中,就會有Location響應報頭域。

Server:  

Server響應報頭域包含了伺服器用來處理請求的軟體資訊。它和User-Agent請求報頭域是相對應的,前者傳送伺服器端軟體的資訊,後者傳送客戶 端軟體(瀏覽器)和作業系統的資訊。下面是Server響應報頭域的一個例子:Server: Apache-Coyote/1.1

WWW-Authenticate:

WWW-Authenticate響應報頭域必須被包含在401(未授權的)響應訊息中,這個報頭域和前面講到的Authorization請求報頭域是 相關的,當客戶端收到401響應訊息,就要決定是否請求伺服器對其進行驗證。如果要求伺服器對其進行驗證,就可以傳送一個包含了 Authorization報頭域的請求,下面是WWW-Authenticate響應報頭域的一個例子:WWW-Authenticate: Basic realm="Basic Auth Test!"

從這個響應報頭域,可以知道伺服器端對我們所請求的資源採用的是基本驗證機制。

Content-Encoding:

Content-Encoding實體報頭域被使用作媒體型別的修飾符,它的值指示了已經被應用到實體正文的附加內容編碼,因而要獲得Content- Type報頭域中所引用的媒體型別,必須採用相應的解碼機制。Content-Encoding主要用語記錄文件的壓縮方法,下面是它的一個例子: Content-Encoding: gzip。如果一個實體正文采用了編碼方式儲存,在使用之前就必須進行解碼。

Content-Language:

Content-Language實體報頭域描述了資源所用的自然語言。Content-Language允許使用者遵照自身的首選語言來識別和區分實體。 如果這個實體內容僅僅打算提供給丹麥的閱讀者,那麼可以按照如下的方式設定這個實體報頭域:Content-Language: da。

如果沒有指定Content-Language報頭域,那麼實體內容將提供給所以語言的閱讀者。

Content-Length:

Content-Length實體報頭域用於指明正文的長度,以位元組方式儲存的十進位制數字來表示,也就是一個數字字元佔一個位元組,用其對應的ASCII碼儲存傳輸。

       要注意的是:這個長度僅僅是表示實體正文的長度,沒有包括實體報頭的長度。

Content-Type :

     Content-Type實體報頭域用語指明發送給接收者的實體正文的媒體型別。例如:

Content-Type: text/html;charset=ISO-8859-1

   Content-Type: text/html;charset=GB2312

Last-Modified :

     Last-Modified實體報頭域用於指示資源最後的修改日期及時間。

Expires :

     Expires實體報頭域給出響應過期的日期和時間。通常,代理伺服器或瀏覽器會快取一些頁面。當用戶再次訪問這些頁面時,直接從快取中載入並顯示給用 戶,這樣縮短了響應的時間,減少伺服器的負載。為了讓代理伺服器或瀏覽器在一段時間後更新頁面,我們可以使用Expires實體報頭域指定頁面過期的時 間。當用戶又一次訪問頁面時,如果Expires報頭域給出的日期和時間比Date普通報頭域給出的日期和時間要早(或相同),那麼代理伺服器或瀏覽器就 不會再使用快取的頁面而是從伺服器上請求更新的頁面。不過要注意,即使頁面過期了,也並不意味著伺服器上的原始資源在此時間之前或之後發生了改變。

      Expires實體報頭域使用的日期和時間必須是RFC 1123中的日期格式,例如:

 Expires: Thu, 15 Sep 2005 16:00:00 GMT

       HTTP1.1的客戶端和快取必須將其他非法的日期格式(也包括0)看作已過期。例如,為了讓瀏覽器不要快取頁面,我們也可以利用Expires實體報頭 域,設定它的值為0,如下(JSP):response.setDateHeader("Expires",0);