前言
說到HTTP,我想大家都知道它是超文本傳輸協議,規定了瀏覽器和服務器之間互相通信的規則。但是如果問你它是怎樣規定的?又是怎樣進行通信的?或許你就會覺得不就是在瀏覽器輸入一個URL,然后服務器返回一個頁面嘛。毫無疑問這樣的理解遠遠不夠,讓你繼續往下說就會覺得好像是這樣又有點詞不達意。其實這說明我們理解的還不夠深,而深入理解HTTP也恰恰是身為前端人員必備的一項技能,網上關於HTTP的解釋很多但也有點難懂,后來我在《HTTP圖解》這本書里看到了用圖片的方式向我們解釋了HTTP,很清晰易懂,所以在這里分享給大家。
一、了解Web及網絡基礎
1、使用HTTP協議訪問Web
你知道當我們在網頁瀏覽器(Web browser)的地址欄中輸入 URL時,Web 頁面是如何呈現的嗎?
Web 頁面當然不能憑空顯示出來。根據 Web 瀏覽器地址欄中指定的URL,Web 瀏覽器從 Web 服務器端獲取文件資源(resource)等信息,從而顯示出 Web 頁面。
像這種通過發送請求獲取服務器資源的 Web 瀏覽器等,都可稱為客戶端(client)。
Web 使用一種名為 HTTP(HyperText Transfer Protocol,超文本傳輸協議 1)的協議作為規范,完成從客戶端到服務器端等一系列運作流程。而協議是指規則的約定。可以說,Web 是建立在 HTTP 協議上通信的。
2、TCP/IP協議族
為了理解 HTTP,我們有必要事先了解一下 TCP/IP 協議族。通常使用的網絡(包括互聯網)是在 TCP/IP 協議族的基礎上運作的。而 HTTP 屬於它內部的一個子集。
計算機與網絡設備要相互通信,雙方就必須基於相同的方法。比如,如何探測到通信目標、由哪一邊先發起通信、使用哪種語言進行通信、怎樣結束通信等規則都需要事先確定。不同的硬件、操作系統之間的通信,所有的這一切都需要一種規則。而我們就把這種規則稱為協議(protocol)。
TCP/IP 是互聯網相關的各類協議族的總稱,如下圖:
3、TCP/IP的分層管理
TCP/IP 協議族里重要的一點就是分層。TCP/IP 協議族按層次分別分 為以下 4 層:應用層、傳輸層、網絡層和數據鏈路層。
把 TCP/IP 層次化是有好處的。比如,如果互聯網只由一個協議統 籌,某個地方需要改變設計時,就必須把所有部分整體替換掉。而分 層之后只需把變動的層替換掉即可。把各層之間的接口部分規划好之 后,每個層次內部的設計就能夠自由改動了。
值得一提的是,層次化之后,設計也變得相對簡單了。處於應用層上 的應用可以只考慮分派給自己的任務,而不需要弄清對方在地球上哪 個地方、對方的傳輸路線是怎樣的、是否能確保傳輸送達等問題。
TCP/IP 協議族各層的作用如下:
4、TCP/TP通信傳輸流
我們來舉一個例子說明這個通信流程,比如說我們想打開某個網頁,流程如下:
- 首先作為發送端的客戶端在應用層(HTTP 協議)發出一個想看某個 Web 頁面的 HTTP 請求。
- 為了傳輸方便,在傳輸層(TCP 協議)把從應用層處收到的數據(HTTP 請求報文)進行分割,並在各個報文上打上標記序號及端口號后轉發給網絡層。
- 在網絡層(IP 協議),增加作為通信目的地的 MAC 地址后轉發給鏈路層。這樣一來,發往網絡的通信請求就准備齊全了。
- 接收端的服務器在鏈路層接收到數據,按序往上層發送,一直到應用層。
- 當傳輸到應用層,才能算真正接收到由客戶端發送過來的 HTTP請求發送端在層與層之間傳輸數據時。
(每經過一層時必定會被打上一個該層所屬的首部信息。反之,接收端在層與層傳輸數據時,每經過一層時會把對應的首部消去。)
5、各種協議和HTTP協議之間的關系
學習了和 HTTP 協議密不可分的 TCP/IP 協議族中的各種協議后,我們再通過這張圖來了解下 IP 協議、TCP 協議和 DNS 服務在使用HTTP 協議的通信過程中各自發揮了哪些作用。
7、URI 和URL
與 URI(統一資源標識符)相比,我們更熟悉 URL(UniformResource Locator,統一資源定位符)。在WWW上,每一信息資源都有統一的且在網上唯一的地址,該地址就叫URL。URL正是使用 Web 瀏覽器等訪問 Web 頁面時需要輸入的網頁地址。比如,下圖的 http://hackr.jp/就是 URL。
URI 用字符串標識某一互聯網資源,而 URL表示資源的地點(互聯網上所處的位置)。可見 URL是 URI 的子集。 接下來我們來看一下URI的格式(在充分理解的基礎上,也可用 URL替換 URI。):
二、HTTP協議
1、客戶端與服務端之間的通信
HTTP 協議規定,請求從客戶端發出,最后服務器端響應該請求並返回。換句話說,肯定是先從客戶端開始建立通信的,服務器端在沒有接收到請求之前不會發送響應。如下:
下面則是從客戶端發送給某個 HTTP 服務器端的請求報文中的內容。
接收到請求的服務器,會將請求內容的處理結果以響應的形式返回。
HTTP 是一種不保存狀態,即無狀態協議。HTTP 協議自身不對請求和響應之間的通信狀態進行保存。也就是說在 HTTP 這個級別,協議對於發送過的請求或響應都不做持久化處理。
使用 HTTP 協議,每當有新的請求發送時,就會有對應的新響應產生。協議本身並不保留之前一切的請求或響應報文的信息。這是為了更快地處理大量事務,確保協議的可伸縮性,而特意把 HTTP 協議設計成如此簡單的。
可是,隨着 Web 的不斷發展,因無狀態而導致業務處理變得棘手的情況增多了。比如,用戶登錄到一家購物網站,即使他跳轉到該站的其他頁面后,也需要能繼續保持登錄狀態。針對這個實例,網站為了能夠掌握是誰送出的請求,需要保存用戶的狀態。
HTTP/1.1 雖然是無狀態協議,但為了實現期望的保持狀態功能,於是引入了 Cookie 技術。有了 Cookie 再用 HTTP 協議通信,就可以管理狀態了。
3、HTTP方法
(1)GET 獲取資源
GET 方法用來請求訪問已被 URL 識別的資源。指定的資源經服務器端解析后返回響應內容。也就是說,如果請求的資源是文本,那就保持原樣返回;如果是像 CGI(通用網關接口)那樣的程序,則返回經過執行后的輸出結果。
GET方法請求響應的例子:
(2)POST傳輸實體的主體
POST 方法用來傳輸實體的主體。雖然用 GET 方法也可以傳輸實體的主體,但一般不用 GET 方法進行傳輸,而是用 POST 方法。雖說 POST 的功能與 GET 很相似,但POST 的主要目的並不是獲取響應的主體內容。
POST方法請求響應的例子:
(3)PUT傳輸文件
PUT 方法用來傳輸文件。就像 FTP 協議的文件上傳一樣,要求在請求報文的主體中包含文件內容,然后保存到請求 URI 指定的位置。但是,鑒於 HTTP/1.1 的 PUT 方法自身不帶驗證機制,任何人都可以上傳文件 , 存在安全性問題,因此一般的 Web 網站不使用該方法。
(4)HEAD獲得報文首部
HEAD 方法和 GET 方法一樣,只是不返回報文主體部分。用於確認URI 的有效性及資源更新的日期時間等。
(5)DELETE刪除文件
DELETE 方法用來刪除文件,是與 PUT 相反的方法。DELETE 方法按請求 URI 刪除指定的資源。其本質和PUT方法一樣不帶驗證機制,所以不適用DELETE方法。
(6)方法歸納
LINK 和 UNLINK 已被 HTTP/1.1 廢棄,不再支持。
4、持久連接節省通信量
HTTP 協議的初始版本中,每進行一次 HTTP 通信就要斷開一次 TCP連接。 以當年的通信情況來說,因為都是些容量很小的文本傳輸,所以即使這樣也沒有多大問題。可隨着 HTTP 的普及,文檔中包含大量圖片的情況多了起來。
比如,使用瀏覽器瀏覽一個包含多張圖片的 HTML頁面時,在發送請求訪問 HTML頁面資源的同時,也會請求該 HTML頁面里包含的其他資源。因此,每次的請求都會造成無謂的 TCP 連接建立和斷開,增加通信量的開銷。
持久連接的好處在於減少了 TCP 連接的重復建立和斷開所造成的額外開銷,減輕了服務器端的負載。另外,減少開銷的那部分時間,使HTTP 請求和響應能夠更早地結束,這樣 Web 頁面的顯示速度也就相應提高了
5、使用Cookie的狀態管理
HTTP 是無狀態協議,它不對之前發生過的請求和響應的狀態進行管理。也就是說,無法根據之前的狀態進行本次的請求處理。
如圖,如果讓服務器管理全部客戶端狀態則會成為負擔。
保留無狀態協議這個特征的同時又要解決類似的矛盾問題,於是引入了 Cookie 技術。Cookie 技術通過在請求和響應報文中寫入 Cookie 信息來控制客戶端的狀態。
Cookie 會根據從服務器端發送的響應報文內的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存 Cookie。當下次客戶端再往該服務器發送請求時,客戶端會自動在請求報文中加入 Cookie 值后發送出去。
服務器端發現客戶端發送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發來的連接請求,然后對比服務器上的記錄,最后得到之前的狀態信息。讓我們來看一下具體過程:
- 沒有 Cookie 信息狀態下的請求
- 第 2 次以后(存有 Cookie 信息狀態)的請求
有了Cookie之后,HTTP請求報文和響應報文的內容如下:
注:本文內容來源自《HTTP圖解》,想詳細了解的同學可以購買本書查閱。