互聯網基礎協議 - HTTP


HTTP

HTTP的簡介

超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網絡協議。所有的WWW文件都必須遵守這個標准。

HTTP是一個基於TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。

HTTP是一個屬於應用層的面向對象的協議,由於其簡捷、快速的方式,適用於分布式超媒體信息系統。它於1990年提出,經過幾年的使用與發展,得到不斷地完善和擴展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的規范化工作正在進行之中,而且HTTP-NG(Next Generation of HTTP)的建議已經提出。

HTTP協議工作於客戶端-服務端架構為上。瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB服務器發送所有請求。Web服務器根據接收到的請求后,向客戶端發送響應信息。

HTTP的特點

  1. 支持客戶/服務器模式。
  2. 簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯系的類型不同。
    由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
  3. 靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
  4. 無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。
  5. 無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

HTTP的URL(UniformResourceLocator)

URL格式:

 http://host[:port][abs_path]

http表示要通過HTTP協議來定位網絡資源。
host表示合法的Internet主機域名或IP地址(以點分十進制格式表示)。
port用於指定一個端口號,擁有被請求資源的服務器主機監聽該端口的TCP連接。
如果port是空,則使用缺省的端口80。當服務器的端口不是80的時候,需要顯式指定端口號。
abs_path指定請求資源的URI(Uniform Resource Identifier,統一資源定位符),如果URL中沒有給出abs_path,那么當它作為請求URI時,必須以“/”的形式給出。通常這個工作瀏覽器就幫我們完成了。

HTTP的請求消息Request

消息格式:
HTTP 消息格式

先來看下HTTP的請求消息頭:

  • Accept: text/html,image/* 【瀏覽器告訴服務器,它支持的數據類型】
  • Accept-Charset: ISO-8859-1 【瀏覽器告訴服務器,它支持哪種字符集】
  • Accept-Encoding: gzip,compress 【瀏覽器告訴服務器,它支持的壓縮格式】
  • Accept-Language: en-us,zh-cn 【瀏覽器告訴服務器,它的語言環境】
  • Host: www.codingme.net:80【瀏覽器告訴服務器,它的想訪問哪台主機】
  • If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT【瀏覽器告訴服務器,緩存數據的時間】
  • Referer: http://www.codingme.net/index.jsp【瀏覽器告訴服務器,客戶機是從那個頁面來的—反盜鏈】
  • 8.User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)【瀏覽器告訴服務器,瀏覽器的內核是什么】
  • Cookie【瀏覽器告訴服務器,帶來的Cookie是什么】
  • Connection: close/Keep-Alive 【瀏覽器告訴服務器,請求完后是斷開鏈接還是保持鏈接】
  • Date: Tue, 11 Jul 2000 18:23:51 GMT【瀏覽器告訴服務器,請求的時間

使用Chrome請求網址進行觀察:

Chrome請求信息

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Cookie:JSESSIONID=2A40A51EDDE663C840A2D03B7587D660; Hm_lvt_1b51c3ea9a3e7b1a2bc55df97ab4efd3=1500964170,1500976171,1500994669,1501056813; Hm_lpvt_1b51c3ea9a3e7b1a2bc55df97ab4efd3=1501056816
Host:blog.codingme.net
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3080.5 Safari/537.36

HTTP的響應消息Response

一個完整的HTTP響應應該包含四個部分:

  1. 一個狀態行【用於描述服務器對請求的處理結果。】
  2. 多個消息頭【用於描述服務器的基本信息,以及數據的描述,服務器通過這些數據的描述信息,可以通知客戶端如何處理等一會兒它回送的數據】
  3. 一個空行
  4. 實體內容【服務器向客戶端回送的數據】

響應消息頭的詳細解釋:

  • Location: http://www.codingme.net/index.jsp 【服務器告訴瀏覽器要跳轉到哪個頁面】
  • Server:apache tomcat【服務器告訴瀏覽器,服務器的型號是什么】
  • Content-Encoding: gzip 【服務器告訴瀏覽器數據壓縮的格式】
  • Content-Length: 80 【服務器告訴瀏覽器回送數據的長度】
  • Content-Language: zh-cn 【服務器告訴瀏覽器,服務器的語言環境】
  • Content-Type: text/html; charset=GB2312 【服務器告訴瀏覽器,回送數據的類型】
  • Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT【服務器告訴瀏覽器該資源上次更新時間】
  • Refresh: 1;url=http://www.codingme.net【服務器告訴瀏覽器要定時刷新】
  • Content-Disposition: attachment; filename=aaa.zip【服務器告訴瀏覽器以下載方式打開數據】
  • Transfer-Encoding: chunked 【服務器告訴瀏覽器數據以分塊方式回送】
  • Set-Cookie:SS=Q0=5Lb_nQ; path=/search【服務器告訴瀏覽器要保存Cookie】
  • Expires: -1【服務器告訴瀏覽器不要設置緩存】
  • Cache-Control: no-cache 【服務器告訴瀏覽器不要設置緩存】
  • Pragma: no-cache 【服務器告訴瀏覽器不要設置緩存】
  • Connection: close/Keep-Alive 【服務器告訴瀏覽器連接方式】
  • Date: Tue, 11 Jul 2000 18:23:51 GMT【服務器告訴瀏覽器回送數據的時間】

Chrome請求網址http://bing.codingme.net 抓包展示;
Chrome 請求信息

HTTP的狀態碼

狀態代碼有三位數字組成,第一個數字定義了響應的類別,共分五種類別:

1xx:指示信息--表示請求已接收,繼續處理

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

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

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

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

常見狀態碼:

  • 200 OK //客戶端請求成功
  • 400 Bad Request //客戶端請求有語法錯誤,不能被服務器所理解
  • 401 Unauthorized //請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用
  • 403 Forbidden //服務器收到請求,但是拒絕提供服務
  • 404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
  • 500 Internal Server Error //服務器發生不可預期的錯誤
  • 503 Server Unavailable //服務器當前不能處理客戶端的請求,一段時間后可能恢復正常

詳情可以查看更多狀態碼

HTTP的請求方法(動作)

HTTP協議中定義了8種方法來表明不同的動作

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

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

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

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

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

  6. DELETE
    請求服務器刪除Request-URL所標識的資源。

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

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

TCP的三次握手

HTTP使用TCP進行輸出傳輸,在建立TCP連接時會進行三次握手。

所謂三次握手(Three-Way Handshake)即建立TCP連接,就是指建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立。在socket編程中,這一過程由客戶端執行connect來觸發,整個流程如下圖所示:

TCP 三次握手

  1. 建立連接時,客戶端發送SYN包(SYN=i)到服務器,並進入到SYN-SEND狀態,等待服務器確認
  2. 服務器收到SYN包,必須確認客戶的SYN(ack=i+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時服務器進入SYN-RECV狀態
  3. 客戶端收到服務器的SYN+ACK包,向服務器發送確認報ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手,客戶端與服務器開始傳送數據。

HTTP協議工作流程

以訪問網站為例,在回車之后所發生的動作:

  1. 瀏覽器向 DNS 服務器請求解析該 URL 中的域名所對應的 IP 地址;
  2. 解析出 IP 地址后,根據該 IP 地址和默認端口 80,和服務器建立TCP連接;
  3. 瀏覽器發出讀取文件(URL 中域名后面部分對應的文件)的HTTP 請求,該請求報文作為 TCP 三次握手的第三個報文的數據發送給服務器;
  4. 服務器對瀏覽器請求作出響應,並把對應的 html 文本發送給瀏覽器;
  5. 釋放 TCP連接;
  6. 瀏覽器將該 html 文本並顯示內容;  

GET請求和POST請求的區別

使用Chrome瀏覽器進行GET請求測試:

Request URL:http://localhost:8888/01-web_servlet/loginServlet?username=zxy&password=123
Request Method:GET
Status Code:200
Remote Address:[::1]:8888
Referrer Policy:no-referrer-when-downgrade

使用Chrome瀏覽器進行POST請求測試:

Request URL:http://localhost:8888/01-web_servlet/loginServlet
Request Method:POST
Status Code:200
Remote Address:[::1]:8888
Referrer Policy:no-referrer-when-downgrade

由測試可以看到GET和POST最明顯的區別就是

  1. GET攜帶的參數傳遞置於URL中以?分割URL和傳輸數據,多個參數用&連接,如果數據是英文字母/數字,原樣發送,如果是空格,轉換為+,如果是中文/其他字符,則直接把字符串用BASE64加密,不安全
    POST把提交的數據放置在是HTTP包的包體中。因此,GET提交的數據會在地址欄中顯示出來,而POST提交,地址欄不會改變
  2. 網上搜索得到如下區別
  3. GET提交的數據大小有限制(因為瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.
  4. GET方式需要使用Request.QueryString來取得變量的值,而POST方式通過Request.Form來獲取變量的值。
  5. GET方式提交數據,會帶來安全問題,比如一個登錄頁面,通過GET方式提交數據時,用戶名和密碼將出現在URL上,如果頁面可以被緩存或者其他人可以訪問這台機器,就可以從歷史記錄獲得該用戶的賬號和密碼.
  6. GET產生一個TCP數據包;POST產生兩個TCP數據包。

<完>

本文作者: 未讀代碼
我的微信:wn8398
個人主頁: www.codingme.net
本篇文章是博主原創文章,歡迎轉載,轉載時在明顯位置注明原文鏈接即可。
關注公眾號回復資源可以獲取Java 核心知識整理&面試資料。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM