詳解 `HTTP` 系列之一
前言
本文介紹的是HTTP的基礎知識,包括HTTP的由來、HTTP的報文資訊、狀態碼、HTTP三個版本的對比等。希望這篇簡短的文章能對大家認識HTTP協議提供幫助。
HTTP的前世今生
當任意兩臺機器需要通訊時,他們必須通過TCP/IP協議進行身份確認和保障通訊安全,之後再進行資料通訊,而HTTP屬於它通訊方式的一個子集,其他的還有FTP、Telnet等。
因此HTTP的工作完全是建立在TCP/IP協議簇之上的,中間或以DNS協議輔助定址。
如果對DNS協議不瞭解的同學,請點此處
連線成功建立後,即可進行HTTP資料傳輸。通俗來講,通訊就類似於兩個人在對話:要做的事、能做的事,這些資訊都包含在請求報文或響應報文中。
報文簡介:
- 請求行/狀態行:基本資訊,包含請求的方法、請求的地址、協議版本等極重要資訊
- 請求頭部/響應頭部:要求的事,比如請求的資料格式、要不要存cookie、返回的資料格式等
- 空行:特殊格式
- 請求包體/響應包體:具體資訊,如要上傳的資訊、伺服器返回的資訊等等
請求報文由請求行、請求頭部、空行 和 請求包體 4 個部分組成,如下圖所示:
請求行: 請求行由方法欄位、URL 欄位 和HTTP 協議版本欄位 3 個部分組成,他們之間使用空格隔開。常用的 HTTP 請求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT;
- GET:當客戶端要從伺服器中讀取某個資源時,使用GET 方法。GET 方法要求伺服器將URL 定位的資源放在響應報文的資料部分,回送給客戶端,即向伺服器請求某個資源。使用GET 方法時,請求引數和對應的值附加在 URL 後面,利用一個問號(“?”)代表URL 的結尾與請求引數的開始,傳遞引數長度受限制。例如,/index.jsp?id=100&op=bind。
- POST:當客戶端給伺服器提供資訊較多時可以使用POST 方法,POST 方法向伺服器提交資料,比如完成表單資料的提交,將資料提交給伺服器處理。GET 一般用於獲取/查詢資源資訊,POST 會附帶使用者資料,一般用於更新資源資訊。POST 方法將請求引數封裝在HTTP 請求資料中,以名稱/值的形式出現,可以傳輸大量資料;
請求頭部:
請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知伺服器有關於客戶端請求的資訊,典型的請求頭有:
- User-Agent:產生請求的瀏覽器型別;
- Accept:客戶端可識別的響應內容型別列表;星號 “ * ” 用於按範圍將型別分組,用 “ /
- Accept-Language:客戶端可接受的自然語言;
- Accept-Encoding:客戶端可接受的編碼壓縮格式;
- Accept-Charset:可接受的應答的字符集;
- Host:請求的主機名,允許多個域名同處一個IP 地址,即虛擬主機;
- connection:連線方式(close 或 keepalive);
- Cookie:儲存於客戶端擴充套件欄位,向同一域名的服務端傳送屬於該域的cookie;
空行: 最後一個請求頭之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有請求頭
請求包體: 請求包體不在 GET 方法中使用,而是在POST 方法中使用。POST 方法適用於需要客戶填寫表單的場合。與請求包體相關的最常使用的是包體型別 Content-Type 和包體長度 Content-Length;
HTTP 響應報文由狀態行、響應頭部、空行 和 響應包體 4 個部分組成,如下圖所示:
狀態行: 狀態行由 HTTP 協議版本欄位、狀態碼和狀態碼的描述文字 3 個部分組成,他們之間使用空格隔開;
-
狀態碼由三位數字組成,它能一定程度上代表伺服器處理請求的狀態。
-
Location:Location響應報頭域用於重定向接受者到一個新的位置。例如:客戶端所請求的頁面已不存在原先的位置,為了讓客戶端重定向到這個頁面新的位置,伺服器端可以發回Location響應報頭後使用重定向語句,讓客戶端去訪問新的域名所對應的伺服器上的資源;
-
Server:Server 響應報頭域包含了伺服器用來處理請求的軟體資訊及其版本。它和 User-Agent 請求報頭域是相對應的,前者傳送伺服器端軟體的資訊,後者傳送客戶端軟體(瀏覽器)和作業系統的資訊。
-
Vary:指示不可快取的請求頭列表;
-
Connection:連線方式;
空行: 最後一個響應頭部之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有響應頭部。
響應包體: 伺服器返回給客戶端的文字資訊;
HTTP相應報文的狀態碼
RFC 規定 HTTP 的狀態碼為「三位數」,第一個數字定義了響應的類別,被分為五類:
接受的請求正在處理,資訊類狀態碼。
- 200 OK 表示從客戶端發來的請求在伺服器端被正確請求。
- 204 No content,表示請求成功,但沒有資源可返回。
- 206 Partial Content,該狀態碼錶示客戶端進行了範圍請求,而伺服器成功執行了這部分的 GET 請求 響應報文中包含由 「Content-Range」 指定範圍的實體內容。
- 301 moved permanently,永久性重定向,表示資源已被分配了新的 URL,這時應該按 Location 首部欄位提示的 URI 重新儲存。
- 302 found,臨時性重定向,表示資源臨時被分配了新的 URL。
- 303 see other,表示資源存在著另一個 URL,應使用 GET 方法獲取資源。
- 304 not modified,當協商快取命中時會返回這個狀態碼。
- 307 temporary redirect,臨時重定向,和302含義相同,不會改變method
當 301、302、303 響應狀態碼返回時,
幾乎所有的瀏覽器都會把 POST 改成 GET,並刪除請求報文內的主體,
之後請求會自動再次傳送 301、302
標準是禁止將 POST 方法改變成 GET 方法的,但實際使用時大家都會這麼做
- 400 bad request,請求報文存在語法錯誤。
- 401 unauthorized,表示傳送的請求需要有通過 HTTP 認證的認證資訊。
- 403 forbidden,表示對請求資源的訪問被伺服器拒絕。
- 404 not found,表示在伺服器上沒有找到請求的資源。
- 405 Method Not Allowed,伺服器禁止使用該方法,客戶端可以通過options方法來檢視伺服器允許的訪問方法
- 500 internal sever error,表示伺服器端在執行請求時發生了錯誤。
- 502 Bad Gateway,伺服器自身是正常的,訪問的時候出了問題,具體啥錯誤我們不知道。
- 503 service unavailable,表明伺服器暫時處於超負載或正在停機維護,無法處理請求
HTTP的優缺點
-
靈活可擴充套件: http非常靈活,在報文中沒有做過多的限制,只要按照其規則可以自己定義欄位,在傳輸中也不僅僅限於txt文字格式,也可以傳輸圖片,視訊,壓縮包等等任意資料。
-
可靠性: 因為http是基於tcp/ip傳輸的,因為tcp/ip是一個連線傳輸協議,因此是是一個可靠(可靠不是安全)的傳輸。
-
無狀態: 因為沒有任何記錄。可以減輕伺服器的負擔,能夠更多的cpu和記憶體用來對外提供服務。因為無狀態,對伺服器無要求,因此可以組成叢集。
- 無狀態: 無狀態也就導致每次請求都要確認身份,這將帶來不必要的操作負擔和資源消耗。(利用cookie技術解決此弊端)
- 明文傳輸: HTTP採用的是明文進行資訊傳遞,將會給資訊被破譯和洩露。(HTTPS很好的解決了這點)
- 請求-問答模式: 此模式下只有一方發起請求,另一方才會相應,這涉及到頻繁的連線斷開操作。同時發起多個請求也會導致“隊頭阻塞”問題的出現。
HTTP三個版本的對比
為了解決HTTP在應用中的諸多問題,HTTP目前出現了三個大版本。
- 任何格式的內容都可以傳送,這使得網際網路不僅可以傳輸文字,還能傳輸影象、視訊、二進位制等檔案。(明文傳輸)
- 除了GET命令,還引入了POST命令和HEAD命令。
- http請求和迴應的格式改變,除了資料部分,每次通訊都必須包括頭資訊(HTTP header),用來描述一些元資料。
- 只使用 header 中的 If-Modified-Since 和 Expires 作為快取失效的標準。
- 不支援斷點續傳,也就是說,每次都會傳送全部的頁面和資料。
- 通常每臺計算機只能繫結一個 IP,所以請求訊息中的 URL 並沒有傳遞主機名(hostname)
- 引入了持久連線( persistent connection),即TCP連線預設不關閉,可以被多個請求複用,不用宣告Connection: keep-alive。長連線的連線時長可以通過請求頭中的
keep-alive
來設定。(不必要的保持會話早加大伺服器的負擔) - 引入了管道機制( pipelining),即在同一個TCP連線裡,客戶端可以同時傳送多個 請求,進一步改進了HTTP協議的效率。(但還是會造成“隊頭阻塞”)
- HTTP 1.1 中新增加了 E-tag,If-Unmodified-Since, If-Match, If-None-Match 等快取控制標頭來控制快取失效。
- 支援斷點續傳,通過使用請求頭中的
Range
來實現。 - 使用了虛擬網路,在一臺物理伺服器上可以存在多個虛擬主機(Multi-homed Web Servers),並且它們共享一個IP地址。
- 新增方法:PUT、 PATCH、 OPTIONS、 DELETE。
- 二進位制分幀: 這是一次徹底的二進位制協議,頭資訊和資料體都是二進位制,並且統稱為"幀":頭資訊幀和資料幀。
- 頭部壓縮: HTTP 1.1版本會出現 「User-Agent、Cookie、Accept、Server、Range」 等欄位可能會佔用幾百甚至幾千位元組,而 Body 卻經常只有幾十位元組,所以導致頭部偏重。HTTP 2.0 使用
HPACK
演算法進行壓縮。 - 多路複用: 複用TCP連線,在一個連線裡,客戶端和瀏覽器都可以同時傳送多個請求或迴應,且不用按順序一一對應,這樣子解決了隊頭阻塞的問題。
- 伺服器推送: 允許伺服器未經請求,主動向客戶端傳送資源,即伺服器推送。(解決了請求-問答模式的弊端)
- 請求優先順序: 可以設定傳送的資料幀的優先順序,讓服務端先處理重要資源,優化使用者體驗。
結語
文中有些內容與圖片來自於他們,包括上野宣老師的出版書籍《圖解HTTP》,
TianTianUP前輩的掘金博文,感謝兩位及其他作者!
時間:2020/08/16 11:09
座標:廣東深圳