Java網絡編程——6.HTTP

超文本傳輸協議(Hypertext Transfer Protocol,HTTP)是一個標準,定義了Web客戶端如何與服務器對話,以及數據如何從服務器傳回客戶端。這一章將深刻後臺,向你展現在瀏覽器的地址欄輸入http://www.baidu.com 並按回車鍵時到底發生了什麼。html

一、HTTP協議

HTTP是Web瀏覽器和Web服務器之間通訊的標準協議,HTTP鏈接使用TCP/IP來傳輸數據,對於從客戶端到服務器的每個請求,都有4個步驟:java

  1. 客戶端在端口(80或其餘端口)打開與服務器的一個TCP鏈接。
  2. 客戶端向服務器發送消息,請求指定路徑上的資源。請求包含一個首部,還能夠有一個空行,後面是這個請求的數據。
  3. 服務器向客戶端發送響應。響應以響應碼開頭,後面是包含元數據的首部、一個空行以及所請求的文檔或錯誤消息。
  4. 服務器關閉鏈接。

這是基本HTTP 1.0過程,在HTTP1.1及之後版本中,能夠經過一個TCP鏈接發送多個請求和響應。每一個請求和響應都有一樣的基本形式:一個首部行、一個包含元數據的HTTP首部、一個空行,而後是一個消息體。通常的客戶端請求以下所示:web

GET / HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Host:money.innovatelife.net
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

第一行稱爲請求行,包括一個方法、資源的路徑及HTTP的版本。瀏覽器

Accept告訴服務器客戶端能夠處理哪些數據類型(但服務器經常忽略這一點),例如MIME類型text/html,類型是text,子類型是html。已經定義了8個頂級類型:緩存

  • text/* 表示人可讀的文字。
  • image/* 表示圖片。
  • model/* 表示3D模型,如VRML文件。
  • audio/* 表示聲音。
  • video/* 表示移動的圖片,可能包括聲音。
  • application/* 表示二進制數據。
  • message/* 表示協議特定的信封,如email消息和HTTP響應。
  • multipart/* 表示多個文檔和資源的容器。

User-Agent是指什麼瀏覽器,Host域來指定服務器的名。安全

請求以一個空行結束,也就是\r\n\r\n,一旦服務器看到這個空行,它就開始經過同一個鏈接向客戶端發送它的響應。一個典型的成功響應以下:服務器

HTTP/1.1 200 OK
Connection:close
Content-Encoding:gzip
Content-Language:zh-CN
Content-Type:text/html;charset=UTF-8
Date:Mon, 24 Apr 2017 08:21:05 GMT
Server:Apache-Coyote/1.1
Via:1.1 money.innovatelife.net (Apache/2.2.15)
Content-length:115
<html>Sample file</html>

第一行指示了服務器使用的協議(HTTP/1.1),後面是一個響應碼,200 OK是最多見的響應碼,表示這個請求是成功的。其餘首部行分別指出了作出請求的日期、服務器軟件(Apache-Coyote)、承諾服務器結束髮送時會關閉鏈接、MIME媒體類型,以及所傳輸文檔的長度。下面列出了HTTP的響應碼:cookie

http狀態返回代碼 1xx(臨時響應)
表示臨時響應並須要請求者繼續執行操做的狀態代碼。

100   (繼續) 請求者應當繼續提出請求。 服務器返回此代碼表示已收到請求的第一部分,正在等待其他部分。 
101   (切換協議) 請求者已要求服務器切換協議,服務器已確認並準備切換。

http狀態返回代碼 2xx (成功)
表示成功處理了請求的狀態代碼。

200   (成功)  服務器已成功處理了請求。 一般,這表示服務器提供了請求的網頁。
201   (已建立)  請求成功而且服務器建立了新的資源。
202   (已接受)  服務器已接受請求,但還沒有處理。
203   (非受權信息)  服務器已成功處理了請求,但返回的信息可能來自另外一來源。
204   (無內容)  服務器成功處理了請求,但沒有返回任何內容。
205   (重置內容) 服務器成功處理了請求,但沒有返回任何內容。
206   (部份內容)  服務器成功處理了部分 GET 請求。

http狀態返回代碼 3xx (重定向)
表示要完成請求,須要進一步操做。 一般,這些狀態代碼用來重定向。

300   (多種選擇)  針對請求,服務器可執行多種操做。 服務器可根據請求者 (user agent) 選擇一項操做,或提供操做列表供請求者選擇。
301   (永久移動)  請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。
302   (臨時移動)  服務器目前從不一樣位置的網頁響應請求,但請求者應繼續使用原有位置來進行之後的請求。
303   (查看其餘位置) 請求者應當對不一樣的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。
304   (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。
305   (使用代理) 請求者只能使用代理訪問請求的網頁。 若是服務器返回此響應,還表示請求者應使用代理。
307   (臨時重定向)  服務器目前從不一樣位置的網頁響應請求,但請求者應繼續使用原有位置來進行之後的請求。

http狀態返回代碼 4xx(請求錯誤)
這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

400   (錯誤請求) 服務器不理解請求的語法。
401   (未受權) 請求要求身份驗證。 對於須要登陸的網頁,服務器可能返回此響應。
403   (禁止) 服務器拒絕請求。
404   (未找到) 服務器找不到請求的網頁。
405   (方法禁用) 禁用請求中指定的方法。
406   (不接受) 沒法使用請求的內容特性響應請求的網頁。
407   (須要代理受權) 此狀態代碼與 401(未受權)相似,但指定請求者應當受權使用代理。
408   (請求超時)  服務器等候請求時發生超時。
409   (衝突)  服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。
410   (已刪除)  若是請求的資源已永久刪除,服務器就會返回此響應。
411   (須要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。
412   (未知足前提條件) 服務器未知足請求者在請求中設置的其中一個前提條件。
413   (請求實體過大) 服務器沒法處理請求,由於請求實體過大,超出服務器的處理能力。
414   (請求的 URI 過長) 請求的 URI(一般爲網址)過長,服務器沒法處理。
415   (不支持的媒體類型) 請求的格式不受請求頁面的支持。
416   (請求範圍不符合要求) 若是頁面沒法提供請求的範圍,則服務器會返回此狀態代碼。
417   (未知足指望值) 服務器未知足"指望"請求標頭字段的要求。

http狀態返回代碼 5xx(服務器錯誤)
這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤多是服務器自己的錯誤,而不是請求出錯。

500   (服務器內部錯誤)  服務器遇到錯誤,沒法完成請求。
501   (還沒有實施) 服務器不具有完成請求的功能。 例如,服務器沒法識別請求方法時可能會返回此代碼。
502   (錯誤網關) 服務器做爲網關或代理,從上游服務器收到無效響應。
503   (服務不可用) 服務器目前沒法使用(因爲超載或停機維護)。 一般,這只是暫時狀態。
504   (網關超時)  服務器做爲網關或代理,可是沒有及時從上游服務器收到請求。
505   (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

HTTP 1.0會爲每一個請求打開一個新鏈接,在HTTP 1.1和之後的版本中,服務器沒必要在發送響應後就關閉鏈接,能夠保持鏈接打開,在同一個socket上等待來自客戶端的新請求。能夠在一個TCP鏈接上連續發送多個請求和響應。不過服務器響應以後,客戶端請求的鎖步模式仍是同樣的。Connection:keep-alive指示它但願重用一個socket。session

二、HTTP方法

與HTTP服務器的通訊遵循一種請求-響應模式:先是一個無狀態的請求,後面是一個無狀態的響應。主要有4個HTTP方法,來標識能夠完成的操做:app

  • GET 請求指定的頁面信息,並返回實體主體。
  • POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會致使新的資源的創建和/或已有資源的修改。
  • PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。它有冪等性(idempotent)。
  • DELETE 從一個指定URL刪除一個資源。

這4個方法不是任意的,它們有特定的語義,應用程序必須遵循這些語義。POST在Web上被大量濫用,不完成提交的全部安全操做應當使用GET而不是POST,現在的主流瀏覽器能夠處理至少2000個字符的查詢字符串。

除了這4個主要的HTTP方法,特殊場合下還會用到另外幾個HTTP方法。HEAD方法相似於GET,只不過返回的響應中沒有具體的內容,用於獲取報頭,這個方法經常使用於檢查文件的修改日期,查看本地緩存中存儲的文件副本是否有效。OPTIONS方法容許客戶端詢問服務器能夠如何處理一個指定的資源,TRACE方法回顯服務器收到的請求,主要用於測試或診斷。

三、請求主體

客戶端除了要提供路徑和查詢字符串,還要提供資源的表示,資源表示在請求主體中發送,放在首部後面,它會按順序發送一下4項:

  1. 一個起始行,包括方法、路徑和查詢字符串,以及HTTP版本。
  2. 一個HTTP首部(Header)。
  3. 一個空行(兩個連續的回車/換行對)。
  4. 主體。

通常來說,主體能夠包含任意的字節,不過,HTTP HEADER要包括兩個字段來指定主體的性質。

  • 一個Content-length字段,指定主體中有多少字節
  • 一個Content-type字段,指定類型的MIME媒體類型(如application/x-www-form-urlencoded)

四、Cookie

不少網站使用一些小文本串在鏈接之間存儲持久的客戶端狀態,這些小文本串稱爲cookie。cookie在請求和響應的首部從服務器傳到客戶端,再從客戶端傳回服務器,服務器使用cookie來指示sessionID、購物車內容、登陸憑據等。

除了簡單的name=value對,cookie能夠有多個屬性來控制它們的做用域,包括過時日期、路徑、域、端口、版本和安全選項。cookie來自哪一個服務器就應用於哪一個服務器,例如一個cookie由*.innovatelife.net設置,瀏覽器就只把這個cookie發回給*.innovatelife.net。cookie的做用域還受路徑限制。設置cookie過時時間,Max-age=3600,3600秒後瀏覽器會刪除這個cookie。

java.net.CookieManager用於存儲和獲取cookie,CookieStore類容許你增長、刪除和列出cookie。具體方法再也不細述。

相關文章
相關標籤/搜索