前言:本文主要是詳解的寫一下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快取機制及原理