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://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的請求消息頭:
- 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 核心知識整理&面試資料。