送給前端 er 一份 HTTP 基礎(chǔ)知識大圖
前言
最近經(jīng)過幾輪的面試之后,被面試官虐得慘慘的,其中許多原因是沒有仔細(xì)的學(xué)過 HTTP 的知識,我對這塊的知識相對來說比較薄弱,所以決定把數(shù)據(jù)結(jié)構(gòu)和算法得先放一放了。所以把 HTTP 的知識學(xué)一遍,然后再補(bǔ)一下JS的基礎(chǔ)。
下面廢話不多說,我們開始吧!
HTTP 是什么
HTTP是一種超文本傳輸協(xié)議,用于完成客戶端和服務(wù)器端等等一系列的運作流程。而協(xié)議指的是規(guī)則的約定??梢哉f,Web 是建立在 HTTP 協(xié)議上進(jìn)行通信的。
HTTP的誕生
我相信大家也是這樣,在學(xué)一門技術(shù)之前都會去了解一下它的歷史,下面來看看 HTTP 的發(fā)展史。
HTTP 誕生于 1989 年 3 月。是一個名叫蒂姆伯納斯-李的哥們兒提出的,最初設(shè)想的基本理念是:借助多文檔之間相互關(guān)聯(lián)形成的超文本,連成可相互參閱的 WWW(World Wide Web,萬維網(wǎng))。簡稱 Web。
HTTP 0.9 在 1990 年問世。那時候的 HTTP 還沒有作為正式的標(biāo)準(zhǔn)被建立。
HTTP 1.0 在 1996 年 5 月 正式作為標(biāo)準(zhǔn)。該協(xié)議標(biāo)準(zhǔn)現(xiàn)在仍然被廣泛使用在服務(wù)器端。
HTTP 1.1 在 1997 年 1 月公布為當(dāng)前主流的 HTTP 協(xié)議版本。
HTTP 2.0 在 2012 年 3 月 征集建議。
HTTP 2.0 在 同年的 9 月份 發(fā)布了第一個草案。
HTTP 2.0 在 2014 年 11 月實現(xiàn)了標(biāo)準(zhǔn)化。
了解 TCP/IP
在理解 HTTP 之前,我們先簡單的來了解一下 TCP/IP 協(xié)議族。一般使用的網(wǎng)絡(luò)都是在 TCP/IP 協(xié)議的基礎(chǔ)上運作的,而 HTTP 屬于它內(nèi)部的一個子集。
TCP/IP 協(xié)議族
在計算機(jī)和網(wǎng)絡(luò)設(shè)備進(jìn)行互相通信時,雙方都必須基于相同的方法。比如,如何探測到通信目標(biāo),是哪邊先發(fā)起通信、用什么語言進(jìn)行通信、怎樣結(jié)束通信等等一些規(guī)則都是先要確定好的。不同的硬件、操作系統(tǒng)之間的通信,所有的這一切都需要一種規(guī)則。而這種規(guī)則稱為協(xié)議。
協(xié)議中包括:從電纜的規(guī)格到 IP 地址的選定方法、尋找異地用戶的方法、雙方建立通信的順序,以及 Web 頁面顯示要處理的步驟,等等。將這些相關(guān)聯(lián)的協(xié)議集合起來總稱為 TCP/IP。
TCP/IP 模型各層作用
TCP/IP 重要的點就是分層。有以下4層:應(yīng)用層、傳輸層、網(wǎng)絡(luò)層和數(shù)據(jù)鏈路層。
TCP四層.png
下面來介紹各層的作用。
- 應(yīng)用層:應(yīng)用層決定了向用戶提供應(yīng)用服務(wù)時通信的活動。比如,F(xiàn)TP(文件傳輸協(xié)議)和 DNS(域名解析系統(tǒng))。HTTP 協(xié)議也在該層。
- 傳輸層:傳輸層對上層應(yīng)用層,提供處于網(wǎng)絡(luò)連接中的兩臺計算機(jī)之間的數(shù)據(jù)傳送。該層有兩個不同的協(xié)議:TCP 傳輸控制協(xié)議和 UDP 用戶數(shù)據(jù)協(xié)議。
- 網(wǎng)絡(luò)層:網(wǎng)絡(luò)層用來處理在網(wǎng)絡(luò)上的數(shù)據(jù)包。數(shù)據(jù)包是網(wǎng)絡(luò)傳輸?shù)淖钚?shù)據(jù)單位。網(wǎng)絡(luò)層的作用就是在多條路線中選出一條傳輸路線進(jìn)行數(shù)據(jù)傳輸。
- 鏈路層:用來處理連接網(wǎng)絡(luò)的硬件部分。包括什么操作系統(tǒng)、硬件的設(shè)備、什么路由器啊之類的等等,都屬于該層。
TCP/IP 層次化的好處是:如果互聯(lián)網(wǎng)由一個協(xié)議統(tǒng)一規(guī)劃,某個地方需要改變設(shè)計時,就必須將所有部分整體替換掉。而分層之后只需要把變動的層替換掉。把各層之間的接口部分規(guī)劃好之后,每層內(nèi)部的設(shè)計就可以自由改動。比如,處于應(yīng)用層上的應(yīng)用可以只考慮分配給自己的任務(wù),不用去考慮其他的問題。
TCP/IP 通信傳輸流
TCP/IP 協(xié)議進(jìn)行通信時,會通過分層順序和對方進(jìn)行通信??蛻舳藦膽?yīng)用層往下走,服務(wù)器端則從鏈路層往上走??聪旅娴膱D。
1.3.1.jpg
- 首先客戶端在應(yīng)用層發(fā)出一個 HTTP 請求。
- 接著,在傳輸層接收到應(yīng)用層的數(shù)據(jù)后進(jìn)行分割,給每個報文打上標(biāo)記序號以及端口號轉(zhuǎn)發(fā)給網(wǎng)絡(luò)層。
- 在網(wǎng)絡(luò)層,添加通信目的地的 MAC 地址后轉(zhuǎn)發(fā)給鏈路層。
- 接收端(也叫服務(wù)器端)的服務(wù)器在鏈路層接收到數(shù)據(jù),按次序向上層發(fā)送,一直到應(yīng)用層。傳輸?shù)綉?yīng)用層才算真正接收到客戶端發(fā)過來的 HTTP 請求。
和HTTP相關(guān)的協(xié)議
在HTTP客戶端向服務(wù)器端發(fā)送報文之前,需要用到 IP、TCP、DNS 這三個和 HTTP 密不可分的協(xié)議。
IP 網(wǎng)絡(luò)協(xié)議
IP(Internet Protocol)網(wǎng)絡(luò)協(xié)議處于網(wǎng)絡(luò)層。IP協(xié)議的作用是把各種數(shù)據(jù)包傳送給對方。但要保證正確的傳送給對方,其中兩個重要的條件是 IP 地址和 MAC 地址??梢园阉胂蟪赡慵业牡刂罚蛘哒f你的電話號碼。
IP 地址指的是節(jié)點被分配到的地址,MAC 地址指的是網(wǎng)卡所屬的固定地址。IP 地址可以跟 MAC 地址進(jìn)行配對。IP 地址是可變的,MAC 地址是不可變的。
IP 和 IP地址別搞混了,IP是一種協(xié)議。而IP地址是則是每臺計算機(jī)的標(biāo)識
ARP 協(xié)議
IP 間的通信依賴 MAC 地址。在網(wǎng)絡(luò)上通信的雙方很少會在同一個局域網(wǎng),一般都是經(jīng)過多臺計算機(jī)或者網(wǎng)絡(luò)設(shè)備中專才能連接到對方。而在中轉(zhuǎn)的過程中,會利用下一站中轉(zhuǎn)設(shè)備的 MAC 地址進(jìn)行搜索下一個中轉(zhuǎn)目標(biāo)。而這時,會用到ARP協(xié)議。ARP協(xié)議是一種用來解析地址的協(xié)議,通過通信方的 IP 地址就能反查出對應(yīng)的 MAC 地址。
在到達(dá)通信目標(biāo)前的中轉(zhuǎn)過程中,計算機(jī)和路由器只能獲取粗略的傳輸路線,這種機(jī)制叫做路由選擇。
就跟你在淘寶上買東西是一樣的道理。比如,你在淘寶網(wǎng)買了件衣服,快遞公司會根據(jù)你的地址進(jìn)行送貨,在送貨這個過程中,并不是直接送到你手里。而是經(jīng)過各種什么杭州中轉(zhuǎn)站然后又到深圳中轉(zhuǎn)站,之后才送到你手里。
TCP 協(xié)議
TCP 協(xié)議處于傳輸層,主要的作用是提供可靠的字節(jié)流服務(wù)。字節(jié)流服務(wù)指的是,為了方便傳輸,將大塊的數(shù)據(jù)分割成以報文段為單位的數(shù)據(jù)包進(jìn)行管理。而可靠性的傳輸服務(wù)指的是,能夠把數(shù)據(jù)準(zhǔn)確可靠的傳給對方。
為了準(zhǔn)確的將數(shù)據(jù)傳送給對方,三次握手就出現(xiàn)了。下圖展示這個過程。
1.4.1.jpg
- 第一次握手:客戶端先發(fā)送一個帶 SYN 標(biāo)志的數(shù)據(jù)包給對方。
- 第二次握手:服務(wù)器端收到之后,回傳一個帶有 SYN/ACK 標(biāo)志的數(shù)據(jù)包表示傳達(dá)確認(rèn)信息。
- 第三次握手:最后,客戶端再傳回一個帶 ACK 標(biāo)志的數(shù)據(jù)包,表示 “握手” 結(jié)束。
DNS 服務(wù)
DNS 服務(wù)和 HTTP協(xié)議一樣,處于應(yīng)用層。它主要的作用是,將域名解析成 IP 地址。DNS 協(xié)議可以通過域名查找 IP 地址,也可以通過 IP 地址反查域名的服務(wù)。
下面展示每個協(xié)議和HTTP協(xié)議的關(guān)系。
什么是URL和URI?
- URL指的是統(tǒng)一資源定位符,是訪問Web網(wǎng)站需要輸入的網(wǎng)站地址。例如,http://www.tutu.com。
- URI指的是統(tǒng)一資源標(biāo)識符,全稱為Uniform Resource Identifier,它的作用是區(qū)分互聯(lián)網(wǎng)中的不同資源。比如,HTML 文檔、圖像、視頻片段、程序等等。而 URL 是 URI 的一個子集。
URI格式
下圖展示了 URI 的格式。
URI.jpg
- 協(xié)議名:http:或https:表示協(xié)議名稱。不區(qū)分字母大小寫,最后加上//。
- 登錄信息:user:pass@ 表示獲取服務(wù)器資源的用戶和密碼。但不推薦使用,因為不安全。
- 服務(wù)器地址:服務(wù)器地址有三種:
- 以域名的形式www.tutu.com;
- 以 IPv4 192.168.0.1地址名;
- 以[0:0:0:0:0:0:1]這種方括號括起來的 IPv6 地址;
- 服務(wù)器端口號::8080表示端口號。
- 文件路徑:/html/index.html表示服務(wù)器文件路徑,資源的訪問位置。
- 查詢字符串:?userId=1表示文件路徑中的參數(shù)。?后面以key=value的形式。如果后面還需要加參數(shù),用&拼接。
- 片段標(biāo)識符:#cn1表示文件中的某個位置。就是平時的網(wǎng)頁錨點定位。
HTTP基礎(chǔ)
HTTP 是一種無狀態(tài)的協(xié)議,對發(fā)送過的請求/響應(yīng)都不做持久化處理。
持久化連接
HTTP 1.1 中的所有連接都是默認(rèn)開啟的(keep-alive)。通過請求/響應(yīng)頭部的Connection字段可以查看是否開啟持久化連接(后面會介紹該字段的值),而在 HTTP1.0中是默認(rèn)關(guān)閉的(close)。
它的特點是,不管是客戶端還是服務(wù)器端,只要其中的一端沒有提出斷開連接,那么就會保持 TCP 連接。好處是,減少 TCP 連接的重復(fù)建立和斷開連接造成的額外開銷,減輕服務(wù)器壓力。這樣使得 HTTP 請求和響應(yīng)速度更快結(jié)束,也提高頁面的顯示速度。
管線化
管線化是不用等待響應(yīng)就可以發(fā)送下一個請求,也就是并行處理。不用一個接一個的等待響應(yīng),管線化比持久化連接還要更快。
HTTP 報文
HTTP 一共有兩種報文:請求報文、響應(yīng)報文。報文又分為報文頭部和報文主體,報文主體是可選的。報文包含了以下三個部分。
- 起始行(start line)有以下兩種類型。
- 請求行:請求的方法、請求的 URL、HTTP的版本
- 響應(yīng)行:HTTP 版本、狀態(tài)碼
- 頭部字段(header):一些頭部信息,以key: value的形式。
- 主體(body):被發(fā)送的數(shù)據(jù)。
報文主體.jpg
這張圖是以請求報文為例。
HTTP 的請求方法
- GET:獲取服務(wù)器資源。
- POST:提交信息給服務(wù)器。
- PUT:傳輸文件。
- HEAD:和 GET 方法一樣。但是只返回響應(yīng)頭部。作用是確定 URL 的有效性和資源更新的時間。
- DELETE:刪除指定的資源。
- OPTIONS:查詢請求服務(wù)器指定的資源所支持的方法。
- TRACE:用來確認(rèn)連接過程中發(fā)生的一些操作。
- CONNECT:建立連接渠道,用于代理服務(wù)器。
HTTP 狀態(tài)碼
1xx
1XX表示接收的請求正在處理。
2xx 成功
- 200 OK:表示客戶端發(fā)送的請求在服務(wù)器端被正常處理了。
- 204 No Content:表示請求被處理成功,但沒有資源可返回。
- 206 Partial Content:表示客戶端只獲取文件的一部分內(nèi)容,而服務(wù)器成功執(zhí)行了這部分的GET請求。響應(yīng)報文中含Content-Range指定部分的實體內(nèi)容。
3xx 重定向
- 301 Moved Permanenty:永久重定向。表示請求的資源已經(jīng)被分配了新的 URL,以后就使用資源現(xiàn)在所指的 URL。
- 302 Found:臨時重定向。表示請求的資源被分配了新的 URL。
- 303 See Other:表示請求的資源存著另一個 URL,應(yīng)該用GET方法獲取請求的資源。
- 304 Not Modified:表示請求已經(jīng)找到,但不符合條件請求。協(xié)商緩存就會返回這個狀態(tài)碼。
- 307 Temporary Redirect:臨時重定向,和302類似。但是補(bǔ)鞥呢改變請求方法。
當(dāng)301、302、303響應(yīng)狀態(tài)碼返回時,幾乎所有瀏覽器都會將POST改為GET,并刪除請求報文中的主體,之后請求會自動再次發(fā)送。301、302標(biāo)準(zhǔn)是禁止把POST改成GET的,但實際使用的時候大家都會這么做。
4xx 客戶端錯誤
- 400 Bad Request:表示請求報文中存在語法錯誤。
- 401 Unauthorized:表示發(fā)送的請求要通過 HTTP 認(rèn)證的認(rèn)證消息。如果之前請求過一次,就表示用戶認(rèn)證失敗。
- 403 Forbidden:表示對請求資源的訪問被服務(wù)器拒絕。
- 404 Not Found:表示服務(wù)器上無法找到請求的資源。
5xx 服務(wù)器錯誤
- 500 Internal Serve Error:表示服務(wù)器端在執(zhí)行請求時發(fā)生錯誤。
- 503 Service Unavailable:表示服務(wù)器暫處于超負(fù)荷或者正在進(jìn)行停機(jī)維護(hù)。
和HTTP相關(guān)Web服務(wù)器
HTTP進(jìn)行通信時,除了客戶端和服務(wù)器端這兩個之外,還有一些用于通信數(shù)據(jù)轉(zhuǎn)發(fā)的應(yīng)用程序。例如代理、網(wǎng)關(guān)、隧道和緩存。
代理
代理是一種具有轉(zhuǎn)發(fā)功能的應(yīng)用程序,它存在于客戶端和服務(wù)器端之間,相當(dāng)于一個中間人。它將客戶端發(fā)送過來的請求并轉(zhuǎn)發(fā)給服務(wù)器端。當(dāng)然,它也會將服務(wù)器端返回的響應(yīng)轉(zhuǎn)發(fā)給客戶端。
代理服務(wù)器.jpg
每次通過代理服務(wù)器轉(zhuǎn)發(fā)請求或響應(yīng)時,頭部都會出現(xiàn)Via這個字段。
網(wǎng)關(guān)
網(wǎng)關(guān)是一種特殊的服務(wù)器,作為其他服務(wù)器的中間實體使用。用于將 HTTP 請求轉(zhuǎn)化成其他協(xié)議通信。網(wǎng)關(guān)接收請求時就好像自己的資源的源服務(wù)器一樣對請求做處理。
網(wǎng)關(guān).jpg
隧道
隧道是可按要求建立一條和其他服務(wù)器的通信線路,到時候使用 SSL 加密進(jìn)行通信。隧道的目的是保證客戶端和服務(wù)器進(jìn)行安全的通信。
隧道.jpg
緩存
緩存是指代理服務(wù)器或客戶端本地磁盤中保存的資源副本。利用緩存可以減少向源服務(wù)器的訪問,主要目的是減少網(wǎng)絡(luò)帶寬的流量和通信時間。
緩存服務(wù)器是代理服務(wù)器的一種,當(dāng)代理轉(zhuǎn)發(fā)從服務(wù)器返回的響應(yīng)時,會保存一份資源的副本。緩存服務(wù)器的優(yōu)點在于通過緩存可以避免多次從源服務(wù)器轉(zhuǎn)發(fā)資源。因此客戶端可就近從緩存服務(wù)器上獲取資源,而源服務(wù)器也不必多次處理相同的請求。
緩存的有效期
每當(dāng)源服務(wù)器上的資源更新時,如果還是用不變的緩存,那就會變成返回更新前的舊資源。
即使存在緩存,也會因為客戶端的要求、緩存的有效期等等一些因素,向源服務(wù)器確認(rèn)資源的有效性。如果緩存的資源已過期,緩存服務(wù)器會向源服務(wù)器上獲取新的資源。
客戶端緩存
這里的客戶端緩存指的是瀏覽器中的緩存。瀏覽器緩存如果未過期,就不用向源服務(wù)器請求相同的資源,直接獲取緩存在本地磁盤中的資源。當(dāng)資源過期時,會向源服務(wù)器確認(rèn)資源的有效性。如果緩存的資源過期,就會再次向源服務(wù)器發(fā)起資源請求。
內(nèi)容協(xié)商
內(nèi)容協(xié)商機(jī)制是指客戶端和服務(wù)器端就響應(yīng)的資源內(nèi)容進(jìn)行互相協(xié)商,然后提供客戶端最合適的資源。內(nèi)容協(xié)商會以語言、字符集、編碼方式等。
主要使用的請求頭有:
- Accept
- Accept-Charset
- Accept-Language
- Content-Language
內(nèi)容協(xié)商技術(shù)有下面三種類型。
- 服務(wù)器驅(qū)動協(xié)商(Server-driven Negotiation)
- 由服務(wù)器進(jìn)行內(nèi)容協(xié)商。
- 客戶端啟動協(xié)商(Agent-driven Negotiation)
- 由客戶端進(jìn)行內(nèi)容協(xié)商。
- 透明協(xié)商 服務(wù)器驅(qū)動和客戶端驅(qū)動的結(jié)合體,由服務(wù)器和客戶端進(jìn)行內(nèi)容協(xié)商的一種方法。
End-to-end頭部和Hop-by-hop頭部
HTTP 頭字段定義成緩存代理和非緩存代理。分為兩種類型。
- 端到端頭部End-to-end
分在這個類別中的頭部會轉(zhuǎn)發(fā)給請求或響應(yīng)對應(yīng)的最終接收目標(biāo),而且必須保存在緩存生成的響應(yīng)中,另外規(guī)定它必須被轉(zhuǎn)發(fā)。
- 逐跳頭部Hop-by-hop
分在這個類別中的頭部只對單次轉(zhuǎn)發(fā)有效,會因通過緩存或代理而不轉(zhuǎn)發(fā)。在 HTTP 1.1 和之后的版本中,如果使用Hop-by-hop頭,就要提供 Connection 頭字段。
除了下面 8 個頭字段外,其他所有字段都屬于端到端頭部。
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade
HTTP通用頭部字段
下面列出請求/響應(yīng)頭都會出現(xiàn)的字段,這些字段都含有重要的信息。
Cache-Control
Cache-Control表示資源的緩存操作,參數(shù)是可選的,如果存在多個參數(shù)的話,以,分隔開。
請求頭
在請求頭中使用Cache-Control字段時,它的值如下:
- no-cache:不使用強(qiáng)緩存,強(qiáng)制向源服務(wù)器再次驗證緩存的資源是否過期(走協(xié)商緩存)。
- no-store:不使用任何緩存,每次都向源服務(wù)器獲取最新的資源。
- max-age:以秒為單位。表示緩存的資源沒有超過指定的時間,客戶端就從緩存中獲取資源。
- min-fresh:以秒為單位。要求代理服務(wù)器返回至少還沒過指定時間的緩存資源。
- max-stale:即使是過期的資源,也照樣接收。
- only-if-cached:告訴代理服務(wù)器,從緩存中獲取資源(如果有)。
- no-transform:不能對資源進(jìn)行轉(zhuǎn)換,可以防止緩存或代理壓縮圖片等類似操作。
響應(yīng)頭
在響應(yīng)頭中使用Cache-Control字段時,它的值如下:
- public:資源可被瀏覽器和代理服務(wù)器進(jìn)行緩存。
- private:資源只可以被瀏覽器進(jìn)行緩存。其他都不可以。
- no-cache:可以緩存,但每次使用前要向源服務(wù)器驗證緩存資源是否過期。
- s-maxage:只提供給代理服務(wù)器,表示代理服務(wù)器中的資源過期時長,用s-maxage后,會忽略max-age和Expires字段。
- max-age:以秒為單位。設(shè)置緩存時間,如果沒超過該時間,不用向服務(wù)器請求資源。如果超過,就證明資源已過期。如果響應(yīng)頭出現(xiàn)Expires字段,在 HTTP 1.1 中會有限處理max-age,而 HTTP1.0 中則相反。
- must-revalidate:可以緩存,但必須向源服務(wù)器再次驗證。如果請求失敗,則返回504狀態(tài)碼。該字段會忽略max-stale。
- proxy-revalidate:要求緩存服務(wù)器對緩存的響應(yīng)有效性進(jìn)行確認(rèn)。
- no-transform:不能對資源進(jìn)行轉(zhuǎn)換,可以防止緩存或代理壓縮圖片等類似操作。
Connection
Connection字段決定當(dāng)前 TCP連接 完成后,是否關(guān)閉連接。有以下兩種。
- keep-Alive:持久化連接。
- close:TCP 連接完成后,立馬關(guān)閉連接。
Date
Date字段的值為GMT時間日期格式,表示 HTTP 報文創(chuàng)建的時間和日期。
- Date: Tue, 13 Apr 2021 12:35:41 GMT
Pragma
Pragma是用來向后兼容只支持 HTTP1.0 協(xié)議的緩存服務(wù)器。它的效果和Cache-Control一樣。
- Pragma: no-cache
Upgrade
Upgrade用于查看 HTTP 協(xié)議或者其他協(xié)議是否可以使用更高的版本進(jìn)行通信。
- Upgrade: HTTP/2.0
- Connection: Upgrade <!-- 表示刪除了Upgrade后再轉(zhuǎn)發(fā) -->
Via
Via用于跟蹤客戶端和服務(wù)器端之間的請求和響應(yīng)報文的傳輸路徑,還可以避免請求循環(huán)的發(fā)生。
- <!-- 經(jīng)過單個代理服務(wù)器 -->
- Via: 1.0 gw.hackr.jp(Squid/3.1)
- <!-- 經(jīng)過多個代理服務(wù)器 -->
- Via: 1.0 gw.hackr.jp(Squid/3.1), 1.1 al.example.com(Squid/2.7)
經(jīng)過代理服務(wù)器 A 時,Via頭部附加了 “1.0 gw.hackr.jp(Squid/3.1)” 這樣的字符串值。行頭 1.0 指的是接收請求的服務(wù)器上應(yīng)用的 HTTP 協(xié)議版本。如果經(jīng)過多個代理服務(wù)器的話,這些信息會后面追加。
Warning
Warning字段告訴用戶一些與緩存有關(guān)的警告。
請求頭字段
Accept
Accept請求頭用來告訴服務(wù)器,客戶端能處理的內(nèi)容類型。下面列出幾種媒體類型。
- 文本文件: text/html、text/plain、text/css、application/xhtml+xml、application/xml等等。
- 圖片文件: image/jpeg、image/gif、image/png;
- 視頻文件: video/mpeg、video/quicktime;
- 二進(jìn)制文件:application/octet-stream、application/zip;
當(dāng)值為*/*,表示客戶端可以是任意內(nèi)容類型。當(dāng)值為image/*,用來代表任何其他圖片類型。
如果想給顯示的媒體類型增加優(yōu)先級,通過用q=表示權(quán)重值,用分號(;)分隔開。權(quán)重值的范圍是0~1,可以精確到小數(shù)點后 3 位,1是最大值。沒有指定權(quán)重值時,默認(rèn)權(quán)重是q=1.0。
- Accept: text/html, appliaction/json;q=0.9
Accept-Charset
Accept-Charset請求頭用來告訴服務(wù)器,客戶端可處理的字符集類型。另外,可以一次性指定多種字符集。和Accept一樣,通過q值來表示優(yōu)先級。該頭部應(yīng)用于內(nèi)容協(xié)商機(jī)制的服務(wù)器驅(qū)動協(xié)商。
- Accept-Charset: iso-8859-1
- Accept-Charset: iso-8859-1;q=0.5
Accept-Encoding
Accept-Encoding請求頭用來告訴服務(wù)器,客戶端能理解的內(nèi)容編碼方式。可以一次性指定多種內(nèi)容編碼,有以下幾種編碼。
- gzip:由文件壓縮程序 gzip 生成的編碼格式,使用 Lempel-Ziv 算法以及 32 位循環(huán)冗余驗證。
- compress:由 UNIX 文件壓縮程序compress生成的編碼方式,采用Lempel-Ziv-Welch算法。
- deflate:組合使用 zlib 格式以及由deflate壓縮算法生成的編碼方式。
- indentity:不執(zhí)行壓縮或不會變化的默認(rèn)編碼格式。
- Accept-Encoding: gzip, deflate
和Accept一樣,用q值來設(shè)置優(yōu)先級。還有使用星號(*),表示指定任意的編碼格式。
Accept-Language
Accept-Language請求頭用來告訴服務(wù)器,客戶端可以理解的自然語言集(指中文和英文集),以及自然語言集的優(yōu)先級。和Accept一樣的,可指定多個自然語言集。使用q值設(shè)置優(yōu)先級。
- Accept-Language: zh-CN,zh;q=0.9;q=0.8
客戶端在服務(wù)器有中文版的情況下,會請求返回中文版的響應(yīng),如果沒有,則返回英文版。
Authorization
Authorization用來告訴服務(wù)器,用戶代理的認(rèn)證信息(證書值)。通常會在服務(wù)器返回401狀態(tài)碼響應(yīng)后,把頭部字段Authorization添加到請求中。
- Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
Expect
Expect用來告訴服務(wù)器,只有在滿足這個條件的情況下才會處理請求。如果服務(wù)器不能滿足客戶端的要求,會返回417狀態(tài)碼。目前只規(guī)定了100-continue這個條件。
- Expect: 100-continue
From
From字段表示用戶代理的用戶的電子郵箱地址,目的是為了顯示搜索引擎用戶代理的負(fù)責(zé)人的電子郵箱聯(lián)系方式。
- From: info@hackr.jp
Host
Host請求頭指明了請求的資源所在的服務(wù)器主機(jī)名和端口號。如果服務(wù)器沒設(shè)置主機(jī)名,會發(fā)送一個空值。
- Host: www.tutu.com
If-Match
像這種If-xxxx開頭的請求頭字段,都是條件請求。服務(wù)器接收到附帶條件的請求后,只判斷條件是真時才會執(zhí)行請求。
If-Match字段用于和服務(wù)器資源的ETag值做對比時,ETag值和If-Match的值相等時才會處理該請求。否則返回412狀態(tài)碼。通過用星號(*)的方式,表示只要資源存在就處理請求,但服務(wù)器會忽略掉ETag的值。
- If-Match: "123456"
If-Modified-Since
If-Modified-Since用于確定代理服務(wù)器或客戶端的資源有效性。在指定的時間之后,請求的資源發(fā)生改變時,就處理請求。如果資源都沒有改變,則返回304狀態(tài)碼。
- If-Modified-Since: Tue, 13 Apr 2021 12:35:41 GMT
If-None-Match
If-None-Match和If-Match相反,只有服務(wù)器資源的ETag的值和If-None-Match的值不一樣時,才會處理該請求。在GET和HEAD請求方法中加入該字段可以獲取最新的資源。
If-Range
If-Range用于告訴服務(wù)器,如果If-Range字段的值和請求資源的ETag值或時間一樣時,就會作為范圍請求處理(Range字段規(guī)定請求多少字節(jié)的數(shù)據(jù))。否則,忽略范圍請求,返回全部資源。
- If-Range: "123456"
- Range: bytes=5001-10000
If-Unmodified-Since
If-Unmodified-Since字段用來告訴服務(wù)器,只有當(dāng)請求資源在指定的時間之后沒有修改的情況下,才會處理請求。如果在指定的時間后發(fā)生了修改,則返回412狀態(tài)碼。
- If-Unmodified-Since: Tue, 13 Apr 2021 12:35:41 GMT
Proxy-Authorization
Proxy-Authorization字段包含了用戶代理提供給代理服務(wù)器用于身份驗證的憑證。
- Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
Range
Range請求頭字段表示獲取資源的哪一部分。服務(wù)器收到帶有Range字段的請求后,會在處理請求之后返回206狀態(tài)碼。如果無法處理,則返回200狀態(tài)碼并把全部資源返回。
- Range: bytes=5001-10000 <!-- bytes=5001-10000為資源的字節(jié) -->
Referer
Referer字段表示請求的URL是從哪個 Web 頁面發(fā)起的。服務(wù)器通過Referer字段來標(biāo)識訪問來源,進(jìn)行統(tǒng)計分析、日志記錄和緩存優(yōu)化。
- Referer: www.tutu.com <!-- 請求是由www.tutu.com發(fā)起的 -->
TE
TE表示客戶端能夠處理響應(yīng)的傳輸編碼方式以及優(yōu)先級。
- TE: gzip, deflate;q=0.5
User-Agent
User-Agent字段用于把請求的瀏覽器和用戶代理名稱等信息傳給服務(wù)器。
- User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36
響應(yīng)頭字段
Accept-Ranges
Accept-Ranges表示服務(wù)器端能處理指定范圍內(nèi)的資源。有兩個值:bytes和none。none表示不能處理指定范圍內(nèi)的請求。
Age
Age表示源服務(wù)器再多久前返回過資源。單位為秒。
- Age: 3600
ETag
ETag表示資源的特定標(biāo)識符,服務(wù)器會給每份資源都分配對應(yīng)的ETag值。當(dāng)資源發(fā)生變化時,ETag值也會改變。例如,訪問同一個 URL 的網(wǎng)站同時具備有中英文版,當(dāng)切換中文時,會返回中文的資源(ETag: user-chi),而切換到英文時,返回的是英文的資源(ETag: user-us)。
強(qiáng)弱ETag
- 強(qiáng)ETag: 不管資源發(fā)生了什么變化都會改變其值。
- ETag: "user-123456"
- 弱ETag: 用于資源是否相同,只有資源發(fā)生了根本改變,產(chǎn)生差異時才會改變ETag值。字段值最開頭會添加W/的字符
- ETag: W/"user-123456"
Location
Location字段表示需要將頁面重定向到某個地址,一般都是響應(yīng)碼為3xx的響應(yīng)才有用。
- Location: www.baidu.com <!-- 重定向到www.baidu.com -->
Proxy-Authenticate
Proxy-Authenticate字段表示獲取代理服務(wù)器的資源要通過身份驗證的方式。
Retry-After
Retry-After字段表示客戶端應(yīng)該在多久之后再次請求。配合503和3xx狀態(tài)碼響應(yīng)一起使用。
- Retry-After: 120
Server
Server字段表示處理請求的服務(wù)器所用到的軟件相關(guān)信息。
- Server: Apache/2.2.17
Vary
Vary字段可以對緩存進(jìn)行控制。從代理服務(wù)器收到源服務(wù)器返回含有Vary指定項的響應(yīng)后,如果要進(jìn)行緩存,那么會對請求中含有Vary指定頭部字段的請求返回緩存。即使對相同資源發(fā)起請求,如果Vary指定的頭部字段不相同,就必須從源服務(wù)器重新獲取資源。
- Vary: Accept-Language
實體頭字段
Allow
Allow用于告訴客戶端,資源所支持的 HTTP 方法,如果服務(wù)器收到不支持的 HTTP 方法時,會返回405狀態(tài)碼作為響應(yīng)。
- Allow: GET, DELETE
Content-Encoding
Content-Encoding字段表示服務(wù)器對實體的主體部分用的內(nèi)容編碼方式。內(nèi)容編碼在Accept-Encoding中已經(jīng)介紹過,一共有4種。
- Content-Encoding: gzip
Content-Language
Content-Language字段表示實體主體使用的自然語言。
- Content-Language: zh-CN
Content-Length
Content-Length表示實體主體部分的大?。ㄒ宰止?jié)為單位)。
- Content-Length: 1500
Content-Location
Content-Location字段表示要返回數(shù)據(jù)的地址。
- Content-Location: https://www.tutu.com/index.html
Content-Range
Content-Range字段表示的是一個數(shù)據(jù)片段在整個文件中的位置。
- Content-Range: bytes 5001-10000/10000
Content-type
Content-type字段表示實體主體中對象的媒體類型。
- Content-type: text/html; charset=UTF-8
Expires
Expires字段會把資源失效的日期告訴客戶端。在這個日期后,資源就會過期。也就是說,在指定的日期內(nèi)可以從瀏覽器緩存中獲取資源。如果超過了這個日期,就必須向服務(wù)器發(fā)起資源請求。如果頭部存在Cache-Control: max-age時,會優(yōu)先處理max-age指令。
- Expires: Tue, 13 Apr 2021 12:35:41 GMT
Last-Modified
Last-Modified字段表示資源最后修改的時間。
- Last-Modified: Tue, 13 Apr 2021 12:35:41 GMT
HTTP 緩存
HTTP 緩存可分為強(qiáng)緩存和協(xié)商緩存,主要用于加快資源的獲取速度,提高用戶體驗,減少網(wǎng)絡(luò)連接,緩解服務(wù)器壓力。
強(qiáng)緩存
對強(qiáng)緩存來說,瀏覽器會判斷請求的資源是否在有效期內(nèi)。如果是在有效期內(nèi),就直接從緩存中讀取資源,不用向服務(wù)器發(fā)送資源請求。強(qiáng)緩存通過Expires、Cache-Control和Pragma這三個頭部字段設(shè)置。
Cache-Control
Cache-Control頭部字段在上面也詳細(xì)介紹過在各端所具備的屬性值。下面來列出最常見的幾個值。
- public: 該資源可以被瀏覽器和代理服務(wù)器進(jìn)行緩存。
- private: 該資源只可以被瀏覽器緩存,其他都不可以。
- no-cache: 不使用強(qiáng)緩存,強(qiáng)制向源服務(wù)器再次驗證緩存的有效性。這個值表示走協(xié)商緩存。
- no-store: 不使用任何緩存,每次都向源服務(wù)器獲取最新資源。
- max-age: 如果緩存的資源沒有超過規(guī)定的時間,客戶端就從緩存中獲取資源。以秒為單位。
- s-maxage: 只適用于代理服務(wù)器,表示代理服務(wù)器中的資源過期時長,用了s-maxage后,會忽略max-age和Expires字段。
Expires
Expires字段的值是一個GMT格式的時間日期,將資源失效的日期告訴客戶端,客戶端收到帶有該字段的響應(yīng)體后進(jìn)行緩存。后續(xù)客戶端發(fā)起相同的資源請求,會用Expires的值和本地時間做對比,如果該請求的本地時間小于Expires的值,就直接用緩存中的資源,不用向服務(wù)器發(fā)起請求。
Expires的值會產(chǎn)生一個問題。如果修改了本地時間,就會導(dǎo)致客戶端和服務(wù)器端的時間不一致,那么對于緩存過期的判斷就無法和預(yù)期一樣了。
Expires在三者中優(yōu)先級最低。
Pragma
Pragma可以看上面的介紹,這里不過多講解。
強(qiáng)緩存在 Chrome 中會返回200狀態(tài)碼并且有兩種情況。
- memory cache: 只要頁面不關(guān)閉,就會從瀏覽器內(nèi)存中獲取資源。
- disk cache: 從磁盤中讀取緩存資源。
強(qiáng)緩存.jpg
用了強(qiáng)緩存后,如果服務(wù)器端的資源更新了,客戶端是不知道的,而且在過期之前都會用緩存中的資源??梢酝ㄟ^Ctrl + F5強(qiáng)制刷新。
協(xié)商緩存
協(xié)商緩存是在用本地緩存之前,會向服務(wù)器發(fā)起一次GET請求,驗證瀏覽器保存在本地的資源是否過期。
last-modified和if-unmodified-sine
一般情況下是用請求資源的最近一次修改時間戳來判斷。來舉個例子:假設(shè)客戶端向服務(wù)器端請求一個文件,為了讓資源被再次請求時能通過協(xié)商緩存機(jī)制使用本地緩存。首次返回該資源的響應(yīng)頭中會包含一個last-modified的字段,字段的值表示資源最后修改的時間。當(dāng)刷新頁面時,該資源使用的是協(xié)商緩存,瀏覽器無法確認(rèn)本地緩存是否過期,然后向服務(wù)器發(fā)起一次GET請求,進(jìn)行緩存有效性的協(xié)商,本次請求的請求頭中包含一個if-unmodified-since字段,字段的值是上次響應(yīng)頭中的last-modified字段的值。
last-modified的不足之處
last-modified存在兩個缺陷:
- 它只是根據(jù)資源最后的修改時間進(jìn)行判斷,雖然請求的文件資源進(jìn)行了編輯,但內(nèi)容并沒有改變,時間也會更新。這就導(dǎo)致了協(xié)商緩存時關(guān)于有效性的判斷驗證失效,就要重新進(jìn)行資源的請求。
- 由于文件資源修改的時間單位是秒,如果文件修改很頻繁。比如,幾百毫秒內(nèi)改一次,就無法識別出該文件資源的更新。
ETag和if-none-match
為了彌補(bǔ)通過時間判斷的不足,HTTP 1.1 加入了ETag(實體標(biāo)簽)的頭信息。
ETag表示資源的特定標(biāo)識符,類似文件指紋。作用上面也有提到,這里不過多講解。
當(dāng)響應(yīng)頭同時存在last-modified和ETag這兩個字段時,會以ETag為準(zhǔn)。再次對該資源發(fā)起請求時,會將之前的響應(yīng)頭中ETag的值當(dāng)作這次請求中if-none-match字段的值,發(fā)送給服務(wù)器進(jìn)行緩存有效性驗證。如果驗證緩存有效,就返回304狀態(tài)碼響應(yīng)重定向到本地緩存。
ETag的不足之處
ETag的出現(xiàn)并不是last-modified的代替品,而是一種補(bǔ)充方案,它還是存在弊端的。
- 如果資源比較大,數(shù)量多而且修改頻繁的話,那么生成ETag的過程會影響到服務(wù)器的性能。
- 上面也講了ETag還分強(qiáng)ETag和弱ETag。
- 強(qiáng)ETag值是根據(jù)資源內(nèi)容進(jìn)行生成,保證每個字節(jié)都相同。
- 弱ETag值是根據(jù)資源的部分屬性值來生成,生成速度快但是無法保證每個字節(jié)都相同。
如果瀏覽器走的是協(xié)商緩存,并且資源沒發(fā)生改變,服務(wù)器端會返回304狀態(tài)響應(yīng)碼告訴瀏覽器獲取本地緩存的資源即可。
1617632172962.jpg
HTTP 的缺點
HTTP協(xié)議主要的不足之處有以下幾點。
- 通信使用明文,內(nèi)容會被竊聽
- 不驗證通信方的身份,可能遭遇偽裝
- 無法證明報文的完整性,可能已遭到篡改
通信使用明文,內(nèi)容會被竊聽
HTTP 協(xié)議本身沒有加密功能,所以無法做到對通信請求和響應(yīng)內(nèi)容進(jìn)行加密。
TCP/IP 是會被竊聽的網(wǎng)絡(luò)
由于 TCP/IP 協(xié)議的工作機(jī)制,通信內(nèi)容在所有通信線路上都有可能遭到窺視。不管是哪個角落的服務(wù)器在跟客戶端進(jìn)行通信,通信的線路上的一些設(shè)備都不可能是個人物品。所以不排除在某個環(huán)節(jié)上遭到惡意窺視的行為。即使進(jìn)行加密處理,也會被窺視到通信的內(nèi)容。竊聽相同端上的通信并不是難事,只要收集在網(wǎng)絡(luò)上流動的數(shù)據(jù)包就行??梢酝ㄟ^抓包和嗅探器工具來收集數(shù)據(jù)包。
解決方案: 加密處理防止竊聽
最常見的兩種加密方式是通信加密和內(nèi)容加密
通信加密
HTTP 協(xié)議中本身沒有加密機(jī)制,但可以通過 SSL(Secure Socket Layer 安全套階層) 或 TLS(Transport Layer Security 安全傳輸層協(xié)議) 的組合使用,加密HTTP的通信內(nèi)容。用 SSL 建立安全通信線路后,就可以在這條線路上進(jìn)行 HTTP 通信。和 SSL 組合使用的 HTTP 叫做 HTTPS (HTTP Secure 超文本傳輸安全協(xié)議) 或 HTTP over SSL。
內(nèi)容加密
由于 HTTP 協(xié)議中沒有加密機(jī)制,那么可以對傳輸?shù)膬?nèi)容本身進(jìn)行加密。也就是把 HTTP 報文中包含的內(nèi)容進(jìn)行加密處理。在這種情況下,客戶端需要對 HTTP 報文主體(body)進(jìn)行加密處理后再發(fā)送請求。要做到內(nèi)容的加密,前提是客戶端和服務(wù)器端同時具有加密和解密的機(jī)制。主要應(yīng)用在 Web 服務(wù)器中。該方式不同于 SSL 和 TLS 把整個通信線路加密處理,所以內(nèi)容還是會有被篡改的可能。
不驗證通信放的身份可能遭遇偽裝
HTTP 協(xié)議的請求和響應(yīng)都不會對通信方進(jìn)行確認(rèn)。
任何人都可以發(fā)起請求
在 HTTP 協(xié)議通信時,由于不存在確定通信方的處理步驟,任何人都可以發(fā)起請求。服務(wù)器只要收到請求,不管是誰都會返回一個響應(yīng)(僅限發(fā)送端的 IP 地址和端口號沒被 Web 服務(wù)器設(shè)置限制訪問的前提下)。也就是來者不拒。
- 有可能是偽裝的服務(wù)器。
- 有可能是偽裝的客戶端。
- 無法確定正在通信的對方是否具備訪問權(quán)限。因為某些 Web 服務(wù)器上保存有重要的信息,只想發(fā)給特定用戶通信的權(quán)限。
- 無法判斷請求是從哪來、出自誰手。
- 即使是無意義的請求也照樣接收。無法阻止大量請求下的 Dos 攻擊(Denial of Service,拒絕服務(wù)器攻擊)。
解決方案:查明對方的證書
雖然使用 HTTP 協(xié)議無法確定通信方,但使用 SSL 可以。SSL 除了加密處理外,還用了一種證書的手段,用于確認(rèn)通信方。證書是由值得信任的第三方機(jī)構(gòu)頒發(fā),用來證明服務(wù)器和客戶端是真實存在的。
通過證書,以證明通信方就是意料中的服務(wù)器,對個人來說,減少了個人信息泄露的危險。另外,客戶端持有證書即可完成個人身份的確認(rèn),也可用于對 Web 網(wǎng)站的認(rèn)證環(huán)節(jié)。
無法證明報文完整性,可能已篡改
收到的內(nèi)容不完整
沒有任何辦法確認(rèn),發(fā)出去的請求或響應(yīng)和接收到的請求或響應(yīng)是前后相同的。有可能在中途被篡改成其他的內(nèi)容,即使內(nèi)容是真的被改了,接收方也不會知道。
解決方案:MD5 和 SHA-1
可以使用 MD5 和 SHA-1 等散列值校驗方法,以及用來確認(rèn)文件的數(shù)字簽名方法(PGP簽名)對內(nèi)容進(jìn)行加密。但是用這些方法也無法保證正確,因為 MD5 和 PGP 本身被修改的話,用戶也不會知道。
HTTPS
HTTP加上加密處理和認(rèn)證以及完整性保護(hù)機(jī)制就是HTTPS
HTTPS 是身披 SSL 外殼的 HTTP
HTTPS 不是應(yīng)用層的一種新協(xié)議。只是 HTTP 通信接口部分用 SSL 和 TLS 協(xié)議代替而已。之前是 HTTP 和 TCP 進(jìn)行通信,用了 SSL 之后,就變成了 HTTP 先和 SSL 通信,之后 SSL 和 TCP 通信。
HTTPS.png
使用 SSL 之后,HTTP 就有了 HTTPS 的加密、證書和完整保護(hù)性這些功能。
加密方式
SSL 用的是公開密鑰加密的處理方式。加密方法中的加密算法是公開的,密鑰則是保密的。通過這種方式可以保持加密方法的安全性。
加密和解密都會用到密鑰。沒有密鑰就沒辦法對密碼解密,任何人只要有密鑰就可以進(jìn)行解密,如果密鑰被攻擊者獲得,那么加密也就沒有意義了。
對稱加密
加密和解密同用一個密鑰的方式叫做共享密鑰加密,也稱為對稱密鑰加密。也就是說,客戶端和服務(wù)器端共用一個密鑰對消息進(jìn)行加密??蛻舳嗽诎l(fā)送請求時,會用密鑰對消息加密。服務(wù)器收到后,再用密鑰對消息進(jìn)行解密。
缺點
對稱加密雖然保證了消息保密性,但客戶端和服務(wù)器端用的都是同一個密鑰,如果說在傳輸?shù)倪^程中出現(xiàn)了中間人或攻擊者。密鑰就有可能落到攻擊者手中,這樣就對消息加密就沒有什么意義了。
非對稱加密
非對稱加密解決了對稱加密的缺點。非對稱加密用的是一對非對稱的密鑰。一把叫做私有密鑰,另一把叫做公開密鑰。私有密鑰只能是自己所擁有,而公開密鑰則是任何人都可以拿到。
當(dāng)客戶端發(fā)送消息前,使用公共密鑰進(jìn)行加密,而服務(wù)器收到消息后,使用私有密鑰進(jìn)行解密。
缺點
非對稱加密需要在發(fā)送端在發(fā)送消息時,用公鑰加密。但公鑰是任何人都可以拿到,中間人也可以。中間人雖然不知道接收方的私鑰是什么,但可以截獲發(fā)送端的公鑰,自己另外生成一把公鑰或者篡改公鑰,把公鑰發(fā)給接收端。而且非對稱加密處理起來比對稱加密的方式更加復(fù)雜,這樣就導(dǎo)致了效率變低。
混合加密機(jī)制
HTTPS 用的就是對稱加密和非對稱加密兩者的混合加密。使用對稱加密的好處是解密效率快,使用非對稱加密的好處是在傳輸消息的過程中不會被破解。即使截獲了數(shù)據(jù),沒有對應(yīng)的私鑰,也無法對消息進(jìn)行破解。
摘要算法
數(shù)字摘要是采用 Hash 函數(shù)將需要加密的明文 “摘要” 成一串固定長度(128位)的密文,這串密文又稱為數(shù)字指紋,它有固定長度,而且不同的明文摘要成密文,其結(jié)果總是不同,而同樣的明文摘要必須一致。數(shù)字摘要是 HTTPS 能確保數(shù)據(jù)完整性和防篡改的根本原因。
數(shù)字簽名
數(shù)字簽名是非對稱加密和數(shù)字摘要兩項技術(shù)的應(yīng)用,它將摘要信息用發(fā)送者的私鑰加密,和原文一起發(fā)給接收者。接收者只有用發(fā)送者的公鑰才能解密被加密的摘要信息,然后用 Hash 函數(shù)對收到的原文產(chǎn)生一個摘要信息,與解密的摘要信息對比。如果一樣,那就說明收到的信息是完整的。否則說明信息被修改過,因此數(shù)字簽名能夠驗證信息的完整性。
數(shù)字簽名是附加在報文上的特殊加密校驗碼。使用數(shù)字簽名有以下兩點好處。
- 簽名能確定消息是由發(fā)送方簽名并發(fā)過來的,因為別人假冒不了發(fā)送方的簽名。
- 簽名能確定消息的完整性,證明數(shù)據(jù)沒有被篡改過。
數(shù)字簽名的過程如下:明文 \-> hash運算 \-> 摘要 \-> 私鑰加密 \-> 數(shù)字簽名
數(shù)字證書
數(shù)字證書(CA)就像我們的身份證一樣,信息都是唯一性的。它是屬于可信任的一些第三方機(jī)構(gòu)所有。證書包含了以下的信息。
- 證書的發(fā)布機(jī)構(gòu) CA
- 證書的有效期
- 公鑰
- 證書所有者
- 簽名
數(shù)字證書還包括對象的公鑰,對象和所用簽名算法的描述信息。所有人都可以創(chuàng)建一個數(shù)字證書,但并不是所有人都能獲得簽發(fā)權(quán),從而為證書信息擔(dān)保,并用它私有密鑰簽發(fā)證書。
HTTPS 的工作流程
- 首先是客戶端向服務(wù)器端發(fā)起一個 HTTPS 請求。
- 服務(wù)器端返回公鑰證書給客戶端。
- 客戶端收到公鑰證書后,用證書的公鑰驗證數(shù)字簽名,以確認(rèn)服務(wù)器的公鑰的真實性。
- 客戶端用隨機(jī)數(shù)生成器生成臨時的會話密鑰,然后用服務(wù)器的公鑰對該會話密鑰進(jìn)行加密,發(fā)送給服務(wù)器端。
- 服務(wù)器收到后,用自己的密鑰對會話密鑰解密。
- 之后客戶端和服務(wù)器端就開始了 HTTPS 通信。
SSL 和 TSL
HTTPS 用的是 SSL(Secure Socket Layer 安全套階層) 和 TLS(Transport Layer Security 安全傳輸層協(xié)議)這兩個協(xié)議。SSL 最開始是網(wǎng)景先倡導(dǎo),后來網(wǎng)景涼了,就轉(zhuǎn)移給了 IETF 的手里。IETF 以 SSL 3.0 為準(zhǔn),之后又定制了 TLS1.0、TLS1.1和 TLS1.2。TLS 是以 SSL 為原型開發(fā)的協(xié)議。有時候統(tǒng)一稱該協(xié)議為 SSL。
為什么不一直用 HTTPS
凡事都具有兩面性,不是說 HTTPS 安全就沒有問題了。其實它還是存在一些問題的。在使用 SSL 時,它的處理速度會變慢。其原因有兩種,一是通信慢,二是每次都進(jìn)行加密通信,就導(dǎo)致消耗大量的 CPU 和內(nèi)存資源,導(dǎo)致處理速度變慢。
- 除了和 TCP 連接、發(fā)送請求和響應(yīng)之外,還要和 SSL 進(jìn)行通信。
- 另外 SSL 要進(jìn)行加密處理,在服務(wù)器和客戶端都要進(jìn)行加密和解密的運算處理。
- 要用 HTTPS 通信,購買證書是必不可少的。
當(dāng)然可以用 SSL 加速(專用服務(wù)器)硬件來改善效率的問題??梢蕴岣?SSL 的計算速度,分擔(dān)負(fù)載。但只有在 SSL 處理時才發(fā)揮 SSL 加速器的效果。像一些非敏感的信息就用 HTTP 進(jìn)行通信,對于敏感信息采用 HTTPS 通信,以節(jié)約資源。
HTTP 和 HTTPS 的區(qū)別
- HTTP 是以明文的方式進(jìn)行傳輸,HTTPS 則是具有安全性的 SSL 加密傳輸協(xié)議。
- HTTP 和 HTTPS 用的是兩種不同的方式進(jìn)行連接,端口號也不一樣。前者是 80,后者是 443。
- 想要用 HTTPS 就得購買證書(CA),而免費的整數(shù)一般都很少,所以需要支付一定的費用。
- HTTPS 對搜索引擎更友好,有利于 SEO ,優(yōu)先索引 HTTPS 的網(wǎng)頁。
- HTTP 的連接簡單,并且是無狀態(tài)的。HTTPS 是由 SSL + HTTP 協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比 HTTP 要安全。
解決 HTTP 1.x 瓶頸的 SPDY
HTTP 1.x的缺點
HTTP 1.x主要有以下幾個缺點:
1. HTTP 1.0 只允許在一個 TCP 連接上發(fā)送一個請求,HTTP 1.1中默認(rèn)允許多個 TCP 連接。但是同一個 TCP 連接中,所有的數(shù)據(jù)通信都是按次序進(jìn)行的,服務(wù)器一般是處理完一個響應(yīng)之后,再繼續(xù)處理下一個。這就造成了隊首阻塞問題。
2. 請求只能從客戶端開始,客戶端不可以接收除了響應(yīng)之外的指令。
3. 請求/響應(yīng)頭部不進(jìn)行壓縮就發(fā)送。頭部信息越多延遲就越大。
4. 發(fā)送冗長的頭部,每次互相發(fā)送相同的頭部導(dǎo)致資源浪費。
5. 可隨意選擇數(shù)據(jù)壓縮格式,非強(qiáng)制壓縮發(fā)送。
SPDY
SPDY 是由谷歌開發(fā)的基于 TCP 協(xié)議的應(yīng)用層協(xié)議。目標(biāo)是為了優(yōu)化 HTTP 協(xié)議的性能,通過壓縮、多路復(fù)用和優(yōu)先級技術(shù),縮短網(wǎng)頁的加載時間并提高安全性。SPDY 協(xié)議的核心思想是盡量減少 TCP 的連接數(shù)。SPDY 并不是一種代替 HTTP 的協(xié)議,而是對 HTTP 協(xié)議的增強(qiáng)。
SPDY 沒有改寫 HTTP 協(xié)議,而是在 TCP/IP的應(yīng)用層和傳輸層之間通過新加會話層的形式運作。同時,考慮到安全問題,SPDY 規(guī)定通信中使用 SSL。
SPDY.jpg
SPDY 以會話層的形式加入,控制對數(shù)據(jù)的流動,但還是采用 HTTP 建立通信。因此,可以照常使用 HTTP 的請求方法、Cookie 以及 HTTP 報文等等。
HTTP 2.0
HTTP 2.0 可以說是 SPDY 的升級版(其實是基于 SPDY 設(shè)計的),但HTTP 2.0和 SPDY 還是存在一些不同的。主要有以下兩點:
- HTTP 2.0 支持明文傳輸,而 SPDY 強(qiáng)制使用 HTTP。
- HTTP 2.0 消息頭的壓縮算法用的是 HPACK,而 SPDY 用的是 DEFLATE。
下面就簡單的介紹一下 HTTP 2.0 新增的功能。由于HTTP 2.0 設(shè)計到的東西太多了,之后我會一篇文章單獨講講 HTTP 2.0。
- 二進(jìn)制分幀層:HTTP 2.0 性能增強(qiáng)的核心就是新增的二進(jìn)制分幀層,HTTP 1.x是以換行符作為純文本的分隔符,而 HTTP 2.0 把所有傳輸?shù)男畔⒎指畛筛〉南⒑蛶?,并對它們采用二進(jìn)制的格式編碼。
- 多向請求和響應(yīng):HTTP 2.0 中心的二進(jìn)制分幀層,將 HTTP 消息分解成獨立的幀,交錯發(fā)送。然后在另一個端根據(jù)流標(biāo)識符和頭部把它們重新組裝。解決了 HTTP 1.x的隊首阻塞問題。
- 請求優(yōu)先級:把 HTTP 消息分解成多個獨立的幀后,就可以通過優(yōu)化這些幀的交錯和傳輸順序進(jìn)一步性能優(yōu)化。
- 服務(wù)器推送:服務(wù)器可以對一個客戶端請求發(fā)送多個響應(yīng)。服務(wù)器還可以向客戶端推送資源而且無需客戶端明確的請求。
- 頭部壓縮:在 HTTP 2.0 中,使用了 HPACK(HTTP2頭部壓縮算法)壓縮格式對傳輸?shù)念^部進(jìn)行編碼,減少了頭部的大小。并在兩端維護(hù)了索引表,用于記錄出現(xiàn)過的頭部,之后在傳輸過程中就可以傳輸已經(jīng)記錄過的頭部健名,對端收到數(shù)據(jù)后就可以通過鍵名找到對應(yīng)的值。
如果想要了解更多 HTTP2.0 的知識可以看看《Web性能權(quán)威指南》這本書,里面講得挺詳細(xì)的。
補(bǔ)充
OSI模型
網(wǎng)絡(luò)架構(gòu)模型除了TCP/IP模型之外,還有OSI模型。OSI模型實際上是多了三層。
OSI模型.png
也就是上面所說的多加了 SSL 和 SPDY 這兩個協(xié)議(都處于應(yīng)用層)。
而數(shù)據(jù)鏈路層細(xì)分的話有兩層:
- 數(shù)據(jù)鏈路層: 在不可靠的物理鏈路上,提供可靠的數(shù)據(jù)傳輸服務(wù)。包括組幀、物理編址、流量控制、差錯控制、接入控制等等。
- 物理層: 主要功能就是連接網(wǎng)絡(luò)設(shè)備。
Cookie
前面也說到,HTTP 是無狀態(tài)的協(xié)議,它不會對之前發(fā)送過的請求和響應(yīng)的狀態(tài)進(jìn)行管理。假設(shè),客戶端的用戶發(fā)送一個請求,服務(wù)器端收到請求后想知道這個請求是哪個家伙發(fā)過來的,那么就要有一個狀態(tài)進(jìn)行管理。而Cookie正是解決這類問題而出現(xiàn)。
從服務(wù)器端返回的響應(yīng)頭信息中有一個Set-Cookie的字段信息,告訴客戶端保存Cookie。在下次客戶端向服務(wù)器端發(fā)送請求時,客戶端會自動在請求頭信息中加入Cookie的值發(fā)送出去。
服務(wù)器收到客戶端發(fā)送過來的Cookie之后,會檢查到底是從哪個客戶端發(fā)送過的請求,然后對比服務(wù)器上的記錄,最后得到了之前的狀態(tài)信息。
Set-Cookie
Set-Cookie是屬于響應(yīng)頭中的一個字段,它包含以下的值。
- NAME=VALUE: Cookie的名稱和值。
- expires=DATE: Cookie的有效期。
- path=PATH: 把服務(wù)器上的文件目錄作為Cookie的使用對象,如果沒有設(shè)置,默認(rèn)是文檔所在的文件目錄。
- domain=域名: 作為Cookie適用對象的域名,如果沒有設(shè)置,默認(rèn)是創(chuàng)建Cookie的服務(wù)器的域名。
- Secure: 只有在 HTTPS 時才會發(fā)送Cookie。
- HttpOnly: JavaScript 不能訪問Cookie。主要是為了防止跨站腳本攻擊時Cookie的信息竊取。
請求頭中的Cookie字段
Cookie是請求頭中的一個字段,它包含服務(wù)器通過Set-Cookie頭部設(shè)置并存到客戶端的值。如果接收多個Cookie時,可以以多個Cookie形式發(fā)送回去。
cookie.jpg
最后
以上是我一個多月在學(xué) HTTP 相關(guān)書籍做的一些筆記。哪里有不對的地方,請各位大佬多多指點!