前言:本文主要是詳解的寫一下Http協議的概念、Http的使用等相關知識。目的呢是為了自己以後複習可以不用到處找資料!因此歡迎走過路過的大佬拍磚(指點),有錯誤的地方我會馬上站好捱打(修改)!
Http概念
Http (HTTP-Hypertext transfer protocol)是超文本傳輸協議, 是一個簡單的請求-響應協議,HTTP基於TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。它通常運行在TCP之上。它指定了客户端可能發送給服務器什麼樣的消息以及得到什麼樣的響應。請求和響應消息的頭以ASCII碼形式給出;而消息內容則具有一個類似MIME的格式。
- HTTP默認端口號為80,但是你也可以改為8080或者其他端口。
- HTTP是無連接的:無連接的含義是限制每次連接只處理一個請求。服務器處理完客户的請求,並收到客户的應答後,即斷開連接。採用這種方式可以節省傳輸時間。
- HTTP是媒體獨立的:這意味着,只要客户端和服務器知道如何處理的數據內容,任何類型的數據都可以通過HTTP發送。客户端以及服務器指定使用適合的MIME-type內容類型。
- HTTP是無狀態的:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。
Http工作方式
HTTP是基於客户/服務器模式,且面向連接的。典型的HTTP事務處理有如下的過程:
(1)客户與服務器建立連接;
(2)客户向服務器提出請求;
(3)服務器接受請求,並根據請求返回相應的文件作為應答;
(4)客户與服務器關閉連接。
URL轉Http報文
Http消息結構
客户端請求消息
請求格式:請求行、請求頭部、空行、請求正文
請求行
包括以下三點:
- 請求方法(get、post等),有關請求方法詳情我會在下一個章節説明
- 請求對應的URL地址,它和報文頭的Host屬性組成完整的請求URL
- 協議名稱及版本號。
GET test HTTP/1.1
複製代碼
請求頭部
請求頭部包含若干個屬性,格式為“頭部字段名:值”,服務端據此獲取客户端的信息。
作用:HTTP消息的元數據(metadata)
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Host: www.juejin.cn
複製代碼
請求正文(請求體)
請求體將一個頁面表單中的組件值通過param1=value1¶m2=value2的鍵值對形式編碼成一個格式化串,它承載多個請求參數的數據。不但請求體體可以傳遞請求參數,請求URL也可以通過類似於“test\name=test&owd=123456”的方式傳遞請求參數
name=test&owd=123456
複製代碼
服務端響應消息
響應格式:狀態行、響應報頭、空行和響應正文。
狀態行
狀態行包括以下:
- 協議版本
- 狀態碼,表示請求是否成功(一般用200表示成功),有關狀態碼我會在其它章節説明
- 狀態描述,代表狀態碼的含義,(比如成功是OK)
HTTP/1.1 200 ok
複製代碼
響應報頭
響應報頭包含若干個屬性,格式為“頭部字段名:值”,客户端據此獲取服務端返回的信息。
作用:HTTP消息的元數據(metadata)
Access-Control-Allow-Origin: *
cache-control: no-cache
Content-Security-Policy: script-src 'self' blob: filesystem:; object-src 'self' blob: filesystem:;
Content-Type: text/css
複製代碼
響應正文
返回給客户端的響應數據,可能是字符數據,也可能是字節數據,是可選的,由服務端決定。
<body>
<!-- test 這僅僅只是一個示例-->
</body>
複製代碼
Http請求方式
- HTTP0.9只支持GET請求。
- HTTP1.0 定義了三種請求方法: GET, POST 和 HEAD方法。
- HTTP1.1 新增了六種請求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
- GET、PUT、DELETE、PATCH是冪等的,POST是非冪等的
Http請求頭信息
大部分的請求頭信息是不需要過多關注的,只需要知道前面幾個常用的就可以了,其他的大致看一眼就好了,還有更多的請求頭字段以及用法等就不一一例舉啦
字段名 | 説明 | 示例 |
---|---|---|
Accept | 指定客户端能夠接收的內容類型 | Accept: text/plain, text/html |
Accept-Charset | 瀏覽器可以接受的字符編碼集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定瀏覽器可以支持的web服務器返回內容壓縮編碼類型。 | Accept-Encoding: compress, gzip |
Accept-Language | 瀏覽器可接受的語言 | Accept-Language: en,zh |
Accept-Ranges | 可以請求網頁實體的一個或者多個子範圍字段 | Accept-Ranges: bytes |
Authorization | HTTP授權的授權證書 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定請求和響應遵循的緩存機制 | Cache-Control: no-cache |
Connection | 表示是否需要持久連接。(HTTP 1.1默認進行持久連接) | Connection: close |
Cookie | HTTP請求發送時,會把保存在該請求域名下的所有cookie值一起發送給web服務器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 請求的內容長度 | Content-Length: 348 |
Content-Type | 請求的與實體對應的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 請求發送的日期和時間 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 請求的特定的服務器行為 | Expect: 100-continue |
From | 發出請求的用户的Email | From: [email protected] |
Host | 指定請求的服務器的域名和端口號 | Host: www.juejin.cn |
If-Match | 只有請求內容與實體相匹配才有效 | If-Match: "737060cd8c284d8af7ad3082f209582d" |
If-Modified-Since | 如果請求的部分在指定時間之後被修改則請求成功,未被修改則返回304代碼 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果內容未改變返回304代碼,參數為服務器先前發送的Etag,與服務器迴應的Etag比較判斷是否改變 | If-None-Match: "737060cd8c284d8af7ad3082f209582d" |
If-Range | 如果實體未改變,服務器發送客户端丟失的部分,否則發送整個實體。參數也為Etag | If-Range: "737060cd8c284d8af7ad3082f209582d" |
If-Unmodified-Since | 只在實體在指定時間之後未被修改才請求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制信息通過代理和網關傳送的時間 | Max-Forwards: 10 |
Pragma | 用來包含實現特定的指令 | Pragma: no-cache |
Proxy-Authorization | 連接到代理的授權證書 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只請求實體的一部分,指定範圍 | Range: bytes=500-999 |
Referer | 先前網頁的地址,當前請求網頁緊隨其後,即來路 | Referer: ....net/test |
TE | 客户端願意接受的傳輸編碼,並通知服務器接受接受尾加頭信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 向服務器指定某種傳輸協議以便服務器進行轉換(如果支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | User-Agent的內容包含發出請求的用户信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中間網關或代理服務器地址,通信協議 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 關於消息實體的警告信息 | Warn: 199 Miscellaneous warning |
Http響應頭信息
大部分的響應頭頭信息是不需要過多關注的,只需要知道前面幾個常用的就可以了,其他的大致看一眼就好了,還有更多的響應頭字段以及用法等就不一一例舉啦
字段名 | 説明 | 示例 |
---|---|---|
Age | 從原始服務器到代理緩存形成的估算時間(以秒計,非負) | Age: 10 |
Accept-Ranges | 表明服務器是否支持指定範圍請求及哪種類型的分段請求 | Accept-Ranges: bytes |
Allow | 服務器支持哪些請求方法(如GET、POST等)。 | Allow: GET, HEAD |
Cache-Control | 告訴所有的緩存機制是否可以緩存及哪種類型 | Cache-Control: no-cache |
Content-Language | 響應體的語言 | Content-Language: en,zh |
Content-Location | 請求資源可替代的備用的另一地址 | Content-Location: /index.htm |
Content-MD5 | 返回資源的MD5校驗值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range | 在整個返回體中本部分的字節位置 | Content-Range: bytes 21010-47021/47022 |
Content-Encoding | 文檔的編碼(Encode)方法。只有在解碼之後才可以得到Content-Type頭指定的內容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時間。Java的GZIPOutputStream可以很方便地進行gzip壓縮,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet應該通過查看Accept-Encoding頭(即request.getHeader("Accept-Encoding"))檢查瀏覽器是否支持gzip,為支持gzip的瀏覽器返回經gzip壓縮的HTML頁面,為其他瀏覽器返回普通頁面。 | Content-Encoding: gzip |
Content-Length | 表示內容長度。只有當瀏覽器使用持久HTTP連接時才需要這個數據。如果你想要利用持久連接的優勢,可以把輸出文檔寫入 ByteArrayOutputStream,完成後查看其大小,然後把該值放入Content-Length頭,最後通過byteArrayStream.writeTo(response.getOutputStream()發送內容。 | Content-Length: 348 |
** Content-Type** | 表示後面的文檔屬於什麼MIME類型。Servlet默認為text/plain,但通常需要顯式地指定為text/html。由於經常要設置Content-Type,因此HttpServletResponse提供了一個專用的方法setContentType。 | Content-Type: text/html; charset=utf-8 |
Date | 當前的GMT時間。你可以用setDateHeader來設置這個頭以避免轉換時間格式的麻煩。 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expires | 應該在什麼時候認為文檔已經過期,從而不再緩存它? | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 文檔的最後改動時間。客户可以通過If-Modified-Since請求頭提供一個日期,該請求將被視為一個條件GET,只有改動時間遲於指定時間的文檔才會返回,否則返回一個304(Not Modified)狀態。Last-Modified也可用setDateHeader方法來設置。 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Location | 表示客户應當到哪裏去提取文檔。Location通常不是直接設置的,而是通過HttpServletResponse的sendRedirect方法,該方法同時設置狀態代碼為302。 | Location: ....net/test |
Pragma | 包括實現特定的指令,它可應用到響應鏈上的任何接收方 | Pragma: no-cache |
Server | 服務器名字。Servlet一般不設置這個值,而是由Web服務器自己設置。 | |
Proxy-Authenticate | 它指出認證方案和可應用到代理的該URL上的參數 | Proxy-Authenticate: Basic |
Http狀態碼
狀態碼 | 描述 | 定義範圍 |
---|---|---|
1xx | 信息,服務器收到請求,需要請求者繼續執行操作 | 100-101 |
2xx | 成功,操作被成功接收並處理 | 200-206 |
3xx | 重定向,需要進一步的操作以完成請求 | 300-307 |
4xx | 客户端錯誤,請求包含語法錯誤或無法完成請求 | 400-423 |
5xx | 服務器錯誤,服務器在處理請求的過程中發生了錯誤 | 500-505 |
這裏介紹幾個常見的狀態碼具體的含義:
- 200 OK 服務器成功處理了請求(這個是我們見到最多的)
- 301/302 Moved Permanently(重定向)請求的URL已移走。Response中應該包含一個Location URL, 説明資源現在所處的位置
- 304 Not Modified(未修改)客户的緩存資源是最新的, 要客户端使用緩存
- 404 Not Found 未找到資源
- 500 服務器遇到一個錯誤,使其無法為請求提供服務
Http版本之間的區別
Http 0.9
- HTTP/0.9是第一個版本的HTTP協議,已過時。它的組成極其簡單,只允許客户端發送GET這一種請求,且不支持請求頭。由於沒有協議頭,造成了HTTP/0.9協議只支持一種內容,即純文本。不過網頁仍然支持用HTML語言格式化,同時無法插入圖片。
- HTTP/0.9具有典型的無狀態性,每個事務獨立進行處理,事務結束時就釋放這個連接。由此可見,HTTP協議的無狀態特點在其第一個版本0.9中已經成型。一次HTTP/0.9的傳輸首先要建立一個由客户端到web服務器的TCP連接,由客户端發起一個請求,然後由web服務器返回頁面內容,然後連接會關閉。如果請求的頁面不存在,也不會返回任何狀態碼。
Http 0.9 VS Http 1.0
Http 1.0 是HTTP協議的第二個版本,開始在客户端與服務端通訊中指定版本號。
比HTTP 0.9 增加了以下特性:
- 請求與響應支持頭部。
- 響應對象以一個響應狀態碼開始。
- 響應對象不只限於超文本。
- 開始支持客户端通過POST方法向web服務器提交數據,支持GET、HEAD、POST方法。
- 支持長連接(但默認還是使用短連接)、緩存機制以及身份認證。
Http 1.0 VS HTTP 1.1
HTTP 1.1 是HTTP協議的第三個版本,目前使用最廣泛以及主流的的協議版本
比HTTP1.0增加了以下內容:
- 默認為長連接
HTTP/1.1支持長連接(PersistentConnection)和請求的流水線(Pipelining)處理,在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲,在HTTP/1.1中默認開啟Connection:keep-alive,一定程度上彌補了HTTP/1.0每次請求都要創建連接的缺點。
- 提供了範圍請求功能(寬帶優化)
在HTTP/1.0中,存在一些浪費帶寬的現象,例如客户端只是需要某個對象的一部分,而服務器卻將整個對象送過來了,並且不支持斷點續傳功能,HTTP/1.1則在請求頭引入了range頭域,它允許值請求資源的某個部分,即返回碼是2.6(Partial Content),這樣就方便了開發者自由的選擇以便於充分利用帶寬和連接。這是支持- 文件斷點續傳的基礎。
- 提供了虛擬主機的功能(HOST域)
在HTTP/1.0中認為每台服務器都綁定一個唯一的IP地址,因此,請求消息中的URL並沒有傳遞主機名(hostname)。但隨着虛擬主機技術的發展,每一台物理服務器上可以存在多個虛擬主機(Multi-homed Web Servers),並且它們共享一個IP地址。HTTP/1.1請求消息和響應消息都應支持Host頭域,且請求消息中如果沒有Host頭域會報告一個錯誤(400 Bad Request)。
- 緩存處理字段
HTTP/1.1在1.0的基礎上加入了一些cache的新特性,引入了實體標籤,一般被稱為e-tags,新增更為強大的Cache-Control頭。
- 錯誤通知的管理
在HTTP/1.1中新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生衝突;410(Gone)表示服務器上的某個資源被永久性的刪除。
Http 1.1 VS Http 2.0
HTTP 2.0 是HTTP協議的第四個版本,比HTTP1.1增加了以下內容:
-
二進制分幀,HTTP/2.0的所有幀都採用二進制編碼。
- 幀:客户端與服務器通過交換幀來通信,幀是基於這個新協議通信的最小單位。
- 消息:指邏輯上的HTTP消息,比如請求、響應等,由一或多個幀組成。
- 流:流是連接中的一個虛擬信道,可以承載雙向的消息;每個流都有一個唯一的整數標識符(1,2…N)。
-
多路複用
多路複用允許同時通過單一的HTTP/2.0連接發起多重的請求-響應消息。有了新的分幀機制後,HTTP/2.0不再依賴多個TCP連接去處理更多併發的請求。每個數據流都拆分成很多互不依賴的幀,而這些幀可以交錯(亂序發送),還可以分優先級。最後再在另一端根據每個幀首部的流標識符把它們重新組合起來。HTTP/2.0連接都是持久化的,而且客户端與服務器之間也只需要一個連接(每個域名一個連接)即可。
-
頭部壓縮
HTTP/1.1的首部帶有大量信息,而且每次都要重複發送。HTTP/2.0要求通訊雙方各自緩存一份首部字段表,從而避免了重複傳輸。
-
請求優先級
瀏覽器可以在發現資源時立即分派請求,指定每個流的優先級,讓服務器決定最優的響應次序。這樣請求就不必排隊了,既節省了時間,也最大限度地利用了每個連接。
-
服務端推送
服務端推送能把客户端所需要的資源伴隨着index.html一起發送到客户端,省去了客户端重複請求的步驟。正因為沒有發起請求,建立連接等操作,所以靜態資源通過服務端推送的方式可以極大地提升速度。
Http緩存機制
感覺需要了解的大佬可以去看看這篇文章,寫的超好的!! 徹底弄懂HTTP緩存機制及原理
Http VS HTTPS
想了解的大佬可以看看這篇文章:關於面試:什麼是Http,什麼是Https
結語
文章若有錯誤之處,歡迎各位大佬指正。才疏學淺,各位的指教將使我越來越棒!
感謝大佬
硬核!30 張圖解 HTTP 常見的面試題
菜鳥教程
HTTP之1 HTTP協議(HTTP協議概述、HTTP消息、緩存控制相關頭部、Cookie相關頭部)
HTTP協議 (六) 狀態碼詳解
『網絡』HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2.0的區別
徹底弄懂HTTP緩存機制及原理