天天看點

HTTP通信協定

作者:so貝塔

HTTP緩存

HTTP 緩存的好處?

  • 減少備援的資料傳輸,節約資源
  • 緩解伺服器壓力,提高網站性能
  • 加快客戶加載網頁的速度

不想使用緩存的幾種方式

  • Ctrl + F5強制重新整理,都會直接向伺服器提取資料
  • 按F5重新整理或浏覽器的重新整理按鈕,預設加上Cache-Control:max-age=0,即會走協商緩存

浏覽器的緩存分類

  • 強緩存 200 (from memory cache)和200 (from disk cache)
  • 協商緩存 304 (Not Modified)

重新整理操作的緩存政策

  • 正常操作:強制緩存有效,協商緩存有效
  • 手動重新整理:強制緩存失效,協商緩存有效
  • 強制重新整理:強制緩存失效,協商緩存失效

緩存流程

強制緩存優先于協商緩存進行,若強制緩存(Expires和Cache-Control)生效則直接使用緩存,若不生效則進行協商緩存(Last-Modified / If-Modified-Since和Etag / If-None-Match),協商緩存由伺服器決定是否使用緩存,若協商緩存失效,那麼代表該請求的緩存失效,重新擷取請求結果,再存入浏覽器緩存中;生效則傳回304,繼續使用緩存,主要過程如下:

HTTP通信協定

強制緩存

如果啟用了強緩存,請求資源時不會向伺服器發送請求,直接從緩存中讀取資源,在chrome控制台的network中看到請求傳回的200狀态碼,并在狀态碼的後面跟着from disk cache 或者from memory cache關鍵字。兩者的差别在于擷取緩存的位置不一樣。

  • Pragma:在 http1.1 中被遺棄
  • Cache-Control:http1.1 時出現的header資訊。設定過期時間(絕對時間、時間點),超過了這個時間點就代表資源過期。但是使用者的本地時間是可以自行調整的,是以會出現問題。max-age=x(機關秒):緩存内容将在x秒後失效,如 Cache-Control:max-age=36000no-cache:用戶端緩存内容,但是是否使用緩存則需要經過協商緩存來驗證決定no-store:所有内容都不會被緩存,即不使用強制緩存,也不使用協商緩存private:所有内容隻有用戶端可以緩存,Cache-Control的預設取值public:所有内容都将被緩存(用戶端和代理伺服器都可緩存)
  • Expires:是http1.0的規範,它的值是一個絕對時間的GMT格式的時間字元串。設定過期時長(相對時間、時間段),指定一個時間長度,跟本地時間無關,在這個時間段内緩存是有效的。同在Response Headers中同為控制緩存過期已被Cache-Control代替

注意:生效優先級為(從高到低):Pragma > Cache-Control > Expires 。

Pragma

在 http1.1 中被遺棄。

Cache-Control

HTTP通信協定

第一步:浏覽器首次發起請求,緩存為空,伺服器響應:

HTTP通信協定

浏覽器緩存此響應,緩存壽命為接收到此響應開始計時 100s 。

第二步:10s 過後,浏覽器再次發起請求,檢測緩存未過期,浏覽器計算 Age: 10 ,然後直接使用緩存,這裡是直接去記憶體中的緩存,from disk 是取磁盤上的緩存:

HTTP通信協定

第三步:100s 過後,浏覽器再次發起請求,檢測緩存過期,向伺服器發起驗證緩存請求。如果伺服器對比檔案已發生改變,則如 1;否則不傳回檔案資料封包,直接傳回 304:

HTTP通信協定

Expires

Expires是HTTP/1.0控制網頁緩存的字段,其值為伺服器傳回該請求的結果緩存的到期時間,即再次發送請求時,如果用戶端的時間小于Expires的值時,直接使用緩存結果。

Expires是HTTP/1.0的字段,但是現在浏覽器的預設使用的是HTTP/1.1,那麼在HTTP/1.1中網頁緩存還是否由Expires控制?到了HTTP/1.1,Expires已經被Cache-Control替代,原因在于Expires控制緩存的原理是使用用戶端的時間與服務端傳回的時間做對比,如果用戶端與服務端的時間由于某些原因(時區不同;用戶端和服務端有一方的時間不準确)發生誤差,那麼強制緩存直接失效,那麼強制緩存存在的意義就毫無意義。

協商緩存

協商緩存(對比緩存)就是由伺服器來确定緩存資源是否可用,是以用戶端與伺服器端要通過某種辨別來進行通信,進而讓伺服器判斷請求資源是否可以緩存通路,這主要涉及到下面兩組header字段。這兩組搭檔都是成對出現的,即第一次請求的響應頭帶上某個字段(Last-Modified或者Etag),則後續請求則會帶上對應的請求字段(If-Modified-Since或者If-None-Match),若響應頭沒有Last-Modified或者Etag字段,則請求頭也不會有對應的字段。

注意:Last-Modified與ETag是可以一起使用的,伺服器會優先驗證ETag,一緻的情況下,才會繼續比對Last-Modified,最後才決定是否傳回304。

ETag/If-None-Match

HTTP通信協定

Etag

Etag是伺服器響應請求時,傳回目前資源檔案的一個唯一辨別(由伺服器生成),如下:

HTTP通信協定

If-None-Match

If-None-Match是用戶端再次發起該請求時,攜帶上次請求傳回的唯一辨別Etag值,通過此字段值告訴伺服器該資源上次請求傳回的唯一辨別值。伺服器收到該請求後,發現該請求頭中含有If-None-Match,則會根據If-None-Match的字段值與該資源在伺服器的Etag值做對比,一緻則傳回304,代表資源無更新,繼續使用緩存檔案;不一緻則重新傳回資源檔案,狀态碼為200,如下:

HTTP通信協定

注意:Etag/If-None-Match優先級高于Last-Modified/If-Modified-Since,同時存在則隻有Etag/If-None-Match生效。

Last-Modified/If-Modified-Since

HTTP通信協定

Last-Modified

Last-Modified是伺服器響應請求時,傳回該資源檔案在伺服器最後被修改的時間,如下:

HTTP通信協定

If-Modified-Since

If-Modified-Since則是用戶端再次發起該請求時,攜帶上次請求傳回的Last-Modified值,通過此字段值告訴伺服器該資源上次請求傳回的最後被修改時間。伺服器收到該請求,發現請求頭含有If-Modified-Since字段,則會根據If-Modified-Since的字段值與該資源在伺服器的最後被修改時間做對比,若伺服器的資源最後被修改時間大于If-Modified-Since的字段值,則重新傳回資源,狀态碼為200;否則則傳回304,代表資源無更新,可繼續使用緩存檔案,如下:

HTTP通信協定

常見問題

問題一:為什麼要有Etag?

你可能會覺得使用Last-Modified已經足以讓浏覽器知道本地的緩存副本是否足夠新,為什麼還需要Etag呢?HTTP1.1中Etag的出現主要是為了解決幾個Last-Modified比較難解決的問題:

一些檔案也許會周期性的更改,但是他的内容并不改變(僅僅改變的修改時間),這個時候我們并不希望用戶端認為這個檔案被修改了,而重新GET; 某些檔案修改非常頻繁,比如在秒以下的時間内進行修改,(比方說1s内修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME隻能精确到秒); 某些伺服器不能精确的得到檔案的最後修改時間。

問題二:如果什麼緩存政策都沒設定,那麼浏覽器會怎麼處理?

如果什麼緩存政策都沒設定,沒有Cache-Control也沒有Expires,對于這種情況,浏覽器會采用一個啟發式的算法(LM-Factor),通常會取響應頭中的 Date 減去 Last-Modified 值的 10% (不同的浏覽器可能不一樣)作為緩存時間。

請求方法

截止到HTTP1.1共有下面幾種方法:

方法 描述
GET GET請求會顯示請求指定的資源。一般來說GET方法應該隻用于資料的讀取,而不應當用于會産生副作用的非幂等的操作中。它期望的應該是而且應該是安全的和幂等的。這裡的安全指的是,請求不會影響到資源的狀态
POST 向指定資源送出資料進行處理請求(例如送出表單或者上傳檔案)。資料被包含在請求體中。POST請求可能會導緻新的資源的建立和/或已有資源的修改
PUT PUT請求會身向指定資源位置上傳其最新内容,PUT方法是幂等的方法。通過該方法用戶端可以将指定資源的最新資料傳送給伺服器取代指定的資源的内容
PATCH PATCH方法出現的較晚,它在2010年的RFC 5789标準中被定義。PATCH請求與PUT請求類似,同樣用于資源的更新。二者有以下兩點不同:1.PATCH一般用于資源的部分更新,而PUT一般用于資源的整體更新。2.當資源不存在時,PATCH會建立一個新的資源,而PUT隻會對已在資源進行更新
DELETE DELETE請求用于請求伺服器删除所請求URI(統一資源辨別符,Uniform Resource Identifier)所辨別的資源。DELETE請求後指定資源會被删除,DELETE方法也是幂等的
OPTIONS 允許用戶端檢視伺服器的性能
CONNECT HTTP/1.1協定中預留給能夠将連接配接改為管道方式的代理伺服器
HEAD 類似于get請求,隻不過傳回的響應中沒有具體的内容,用于擷取報頭
TRACE 回顯伺服器收到的請求,主要用于測試或診斷

頭參數

常見請求頭

名稱 作用
Authorization 用于設定身份認證資訊
User-Agent 使用者辨別,如:OS和浏覽器的類型和版本
If-Modified-Since 值為上一次伺服器傳回的 Last-Modified 值,用于确認某個資源是否被更改過,沒有更改過(304)就從緩存中讀取
If-None-Match 值為上一次伺服器傳回的 ETag 值,一般會和If-Modified-Since一起出現
Cookie 已有的Cookie
Referer 表示請求引用自哪個位址,比如你從頁面A跳轉到頁面B時,值為頁面A的位址
Host 請求的主機和端口号

常見響應頭

名稱 作用
Date 伺服器的日期
Last-Modified 該資源最後被修改時間
Transfer-Encoding 取值為一般為chunked,出現在Content-Length不能确定的情況下,表示伺服器不知道響應版體的資料大小,一般同時還會出現Content-Encoding響應頭
Set-Cookie 設定Cookie
Location 重定向到另一個URL,如輸入浏覽器就輸入baidu.com回車,會自動跳到 https://www.baidu.com ,就是通過這個響應頭控制的
Server 背景伺服器

狀态碼

HTTP狀态碼由三個十進制數字組成,第一個十進制數字定義了狀态碼的類型,後兩個數字沒有分類的作用。HTTP狀态碼共分為5種類型:

分類 分類描述
1xx 資訊,伺服器收到請求,需要請求者繼續執行操作
2xx 成功,操作被成功接收并處理
3xx 重定向,需要進一步的操作以完成請求
4xx 用戶端錯誤,請求包含文法錯誤或無法完成請求
5xx 伺服器錯誤,伺服器在處理請求的過程中發生了錯誤

一般我們隻需要知道幾個常見的就行,比如 200,400,401,403,404,500,502。

請求流程

說下浏覽器請求一個網址的過程?

  • 首先通過DNS伺服器把域名解析成IP位址,通過IP和子網路遮罩判斷是否屬于同一個子網
  • 構造應用層請求http封包,傳輸層添加TCP/UDP頭部,網絡層添加IP頭部,資料鍊路層添加以太網協定頭部
  • 資料經過路由器、交換機轉發,最終達到目标伺服器,目标伺服器同樣解析資料,最終拿到http封包,按照對應的程式的邏輯響應回去
HTTP通信協定

常見問題

http1.1和http2的差別

HTTP1.1

  • 持久連接配接
  • 請求管道化
  • 增加緩存處理(新的字段如cache-control)
  • 增加 Host 字段、支援斷點傳輸等

HTTP2.0

  • 二進制分幀
  • 多路複用(或連接配接共享)
  • 頭部壓縮
  • 伺服器推送

HTTP 和HTTPS的差別

(1)HTTPS 協定需要到 CA 申請證書,一般免費證書較少,因而需要一定費用。

(2)HTTP 是超文本傳輸協定,資訊是明文傳輸,HTTPS 則是具有安全性的 SSL 加密傳輸協定。

(3)HTTP 和 HTTPS 使用的是完全不同的連接配接方式,用的端口也不一樣,前者是80,後者是443。

(4)HTTP 的連接配接很簡單,是無狀态的;HTTPS 協定是由 SSL+HTTP 協定建構的可進行加密傳輸、身份認證的網絡協定,比 HTTP 協定安全。

對稱加密和非對稱加密

對稱密鑰加密是指加密和解密使用同一個密鑰的方式,這種方式存在的最大問題就是密鑰發送問題,即如何安全地将密鑰發給對方;

而非對稱加密是指使用一對非對稱密鑰,即公鑰和私鑰,公鑰可以随意釋出,但私鑰隻有自己知道。發送密文的一方使用對方的公鑰進行加密處理,對方接收到加密資訊後,使用自己的私鑰進行解密。

由于非對稱加密的方式不需要發送用來解密的私鑰,是以可以保證安全性;但是和對稱加密比起來,它比較慢,是以我們還是要用對稱加密來傳送消息,但對稱加密所使用的密鑰我們可以通過非對稱加密的方式發送出去。

常見狀态碼

1×× : 請求進行中,請求已被接受,正在處理

2×× : 請求成功,請求被成功處理 200 OK

3×× : 重定向,要完成請求必須進行進一步處理 301 : 永久性轉移 302 :暫時性轉移 304 :已緩存

4×× : 用戶端錯誤,請求不合法 400:Bad Request,請求有文法問題 403:拒絕請求 404:用戶端所通路的頁面不存在

5×× : 伺服器端錯誤,伺服器不能處理合法請求 500 :伺服器内部錯誤 503 :服務不可用,稍等

Session、Cookie 的差別

  • session 在伺服器端,cookie 在用戶端(浏覽器)
  • session 預設被存儲在伺服器的一個檔案裡(不是記憶體)
  • session 的運作依賴 session id,而 session id 是存在 cookie 中的,也就是說,如果浏覽器禁用了 cookie ,同時 session 也會失效(但是可以通過其它方式實作,比如在 url 中傳遞 session_id)
  • session 可以放在 檔案、資料庫、或記憶體中都可以。
  • 使用者驗證這種場合一般會用 session

繼續閱讀