互聯網基礎協議 – HTTP
- 2019 年 10 月 30 日
- 筆記
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的特點
- 支援客戶/伺服器模式。
- 簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯繫的類型不同。
由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。 - 靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
- 無連接:無連接的含義是限制每次連接只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。
- 無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。
HTTP的URL(UniformResourceLocator)
URL格式:
http
表示要通過HTTP協議來定位網路資源。
host
表示合法的Internet主機域名或IP地址(以點分十進位格式表示)。
port
用於指定一個埠號,擁有被請求資源的伺服器主機監聽該埠的TCP連接。
如果port是空,則使用預設的埠80
。當伺服器的埠不是80的時候,需要顯式指定埠號。
abs_path
指定請求資源的URI(Uniform Resource Identifier,統一資源定位符),如果URL中沒有給出abs_path,那麼當它作為請求URI時,必須以「/」的形式給出。通常這個工作瀏覽器就幫我們完成了。
HTTP的請求消息Request
消息格式:
先來看下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響應應該包含四個部分:
- 一個狀態行【用於描述伺服器對請求的處理結果。】
- 多個消息頭【用於描述伺服器的基本資訊,以及數據的描述,伺服器通過這些數據的描述資訊,可以通知客戶端如何處理等一會兒它回送的數據】
- 一個空行
- 實體內容【伺服器向客戶端回送的數據】
響應消息頭的詳細解釋:
- 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 抓包展示;
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種方法來表明不同的動作
-
OPTIONS
返回伺服器針對特定資源所支援的HTTP請求方法,也可以利用向web伺服器發送『*』的請求來測試伺服器的功能性。 -
HEAD
向伺服器索與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以再不必傳輸整個響應內容的情況下,就可以獲取包含在響應小消息頭中的元資訊。 -
GET
向特定的資源發出請求。注意:GET方法不應當被用於產生「副作用」的操作中,例如在Web Application中,其中一個原因是GET可能會被網路蜘蛛等隨意訪問。
Loadrunner中對應get請求函數:web_link和web_url. -
POST
向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。 Loadrunner中對應POST請求函數:web_submit_data,web_submit_form. -
PUT
向指定資源位置上傳其最新內容。 -
DELETE
請求伺服器刪除Request-URL所標識的資源。 -
TRACE
回顯伺服器收到的請求,主要用於測試或診斷。 -
CONNECT
HTTP/1.1協議中預留給能夠將連接改為管道方式的代理伺服器。
TCP的三次握手
HTTP使用TCP進行輸出傳輸,在建立TCP連接時會進行三次握手。
所謂三次握手(Three-Way Handshake)即建立TCP連接,就是指建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立。在socket編程中,這一過程由客戶端執行connect來觸發,整個流程如下圖所示:
- 建立連接時,客戶端發送SYN包(SYN=i)到伺服器,並進入到SYN-SEND狀態,等待伺服器確認
- 伺服器收到SYN包,必須確認客戶的SYN(ack=i+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時伺服器進入SYN-RECV狀態
- 客戶端收到伺服器的SYN+ACK包,向伺服器發送確認報ACK(ack=k+1),此包發送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手,客戶端與伺服器開始傳送數據。
HTTP協議工作流程
以訪問網站為例,在回車之後所發生的動作:
- 瀏覽器向 DNS 伺服器請求解析該 URL 中的域名所對應的 IP 地址;
- 解析出 IP 地址後,根據該 IP 地址和默認埠 80,和伺服器建立TCP連接;
- 瀏覽器發出讀取文件(URL 中域名後面部分對應的文件)的HTTP 請求,該請求報文作為 TCP 三次握手的第三個報文的數據發送給伺服器;
- 伺服器對瀏覽器請求作出響應,並把對應的 html 文本發送給瀏覽器;
- 釋放 TCP連接;
- 瀏覽器將該 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最明顯的區別就是
- GET攜帶的參數傳遞置於URL中以?分割URL和傳輸數據,多個參數用&連接,如果數據是英文字母/數字,原樣發送,如果是空格,轉換為+,如果是中文/其他字元,則直接把字元串用BASE64加密,
不安全
,
POST把提交的數據放置在是HTTP包的包體中。因此,GET提交的數據會在地址欄中顯示出來,而POST
提交,地址欄不會改變
- 網上搜索得到如下區別
- GET提交的數據大小有限制(因為瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.
- GET方式需要使用Request.QueryString來取得變數的值,而POST方式通過Request.Form來獲取變數的值。
- GET方式提交數據,會帶來安全問題,比如一個登錄頁面,通過GET方式提交數據時,用戶名和密碼將出現在URL上,如果頁面可以被快取或者其他人可以訪問這台機器,就可以從歷史記錄獲得該用戶的帳號和密碼.
- GET產生一個TCP數據包;POST產生兩個TCP數據包。
<完>
我的微信:wn8398
個人主頁:www.codingme.net
本篇文章是部落客原創文章,歡迎轉載,轉載時在明顯位置註明原文鏈接即可。
關注公眾號回復資源可以獲取Java 核心知識整理&面試資料。