日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于HTTP缓存的故事

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于HTTP缓存的故事 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近面試被問到了HTTP緩存的內容,沒有了解過太多,只是在某些文章中看到過,知道強緩存和協商緩存這倆名詞,具體是什么并沒有了解過。
關于前端的緩存其實大致就可以區分為瀏覽器緩存和HTTP緩存,平時可能在業務開發中用到瀏覽器緩存會比較多,今天學習一下HTTP緩存的內容

啥是HTTP緩存

HTTP緩存指的是: 當客戶端向服務器請求資源時,會先抵達瀏覽器緩存,如果瀏覽器有要請求資源的副本,就可以直接從瀏覽器緩存中提取而不是從原始服務器中提取這個資源。

常見的HTTP緩存只能緩存GET請求響應的資源,對于其它類型的響應則無能為力,所以后續說的請求緩存都是指GET請求。

HTTP緩存都是從第二次請求開始的。第一次請求資源時,服務器返回資源,并在response header頭中回傳資源的緩存參數;第二次請求時,瀏覽器判斷這些請求參數,命中強緩存直接200,否則就把請求參數加到request header頭中傳給服務器,看是否命中協商緩存,命中則返回304,否則服務器會返回新的資源。

HTTP緩存的分類

根據是否需要重新向服務器發起請求來分類,可分為(強緩存, 協商緩存)根據是否可以被單個或者多個用戶使用來分類,可分為(私有緩存,共享緩存)強緩存如何生效,不需要再和服務器發生交互,而協商緩存不管是否生效,都需要與服務端發生交互。下面是強緩存和協商緩存的一些對比:

強緩存協商緩存
緩存存放位置本地瀏覽器本地瀏覽器
HTTP狀態碼200304
誰來決定Pragma
Cache-Control
Expires
ETag/If-Not-Match
Last-Modified/If-Modified-
操作是否有效1、Ctrl + F5強制刷新 —無效
2、F5刷新 -----------------無效
3、 地址欄回車 -----------有效
4、 頁面鏈接跳轉 --------有效
5、新開窗口 ---------------有效
6、前進、后退 ------------有效
1、Ctrl + F5強制刷新 —無效
2、F5刷新 -----------------有效
3、 地址欄回車 -----------有效
4、 頁面鏈接跳轉 --------有效
5、新開窗口 --------------有效
6、前進、后退 -----------有效

強緩存

強制緩存在緩存數據未失效的情況下(即CaChe-Control的max-age沒有過期或者Expires的緩存時間沒有過期),那么就會直接使用瀏覽器的緩存數據,不會再向服務器發送任何請求。強制緩存生效時,HTTP狀態碼為200。這種方式頁面的加載速度是最快的,性能也不是很好的,但是在這期間,如果服務器端的資源修改了,頁面上是拿不到的,因為它不會再向服務器發請求了。這種情況就是我們在開發中經常遇到的,比如你修改了頁面上的某個樣式,在頁面上刷新了但沒有生效,因為走的是強緩存,所以Ctrl + F5一頓操作之后就好了。跟強制緩存相關的header頭屬性有(Pragma/Cache-Control/Expires)

header屬性可選值優先級優缺點
Pragma(HTTP/1.0)no-cache: 不直接使用緩存,根據新鮮度來使用緩存1、響應頭不支持這個屬性
2、為了兼容HTTP/1.0的客戶端
3、 在HTTP1.1中已被廢棄
Cache-Control(HTTP/1.1)1、no-cache: 不直接使用緩存,根據新鮮度來使用緩存
2、 no-store: 不使用緩存,每次都是請求下載新資源
3、max-age: xx秒,緩存時長
4、 public/private: 是否只能被單個用戶使用,默認為private
5、 must-revalidate: 每次訪問需要緩存校驗
1、請求頭和響應頭都支持這個屬性
2、不適用于HTTP/1.0
3、在緩存未失效前,獲取不到修改后的資源
Expires(HTTP/1.0+)GMT時間1、服務器和客戶端的時間不一致會出問題
2、適用于HTTP/1.0和HTTP1.1
3、在緩存未失效前,獲取不到修改后的資源

這個Pragma和Cache-Control共存時的優先級問題還有點異議,我在不同的文章里發現:有的說Pragma的優先級更高,有的說Cache-Control高。為了搞清楚這個問題,我決定動手操作一波,首先我用nodejs搭建后臺服務器,目的是設置緩存參數,具體代碼如下:


然后再瀏覽器上訪問:http://localhost:8888
第一次訪問時都是從后臺返回的數據:


第二次訪問時:



最終得出結論:
Pragma和Cache-control共存時,Pragma的優先級是比Cache-Control高的。

注意:
在chrome瀏覽器中返回的200狀態會有兩種情況:
1、from memory cache
(從內存中獲取/一般緩存更新頻率較高的js、圖片、字體等資源)

2、from disk cache
(從磁盤中獲取/一般緩存更新頻率較低的js、css等資源)

這兩種情況是chrome自身的一種緩存策略,這也是為什么chrome瀏覽器響應的快的原因。其他瀏覽返回的是已緩存狀態,沒有標識是從哪獲取的緩存。

chrome瀏覽器:


Firefox瀏覽器:

協商緩存

當第一次請求時服務器返回的響應頭中沒有Cache-Control和Expires或者Cache-Control和Expires過期還或者它的屬性設置為no-cache時(即不走強緩存),那么瀏覽器第二次請求時就會與服務器進行協商,與服務端對比判斷資源是否進行了修改更新。如果服務端的資源沒有修改,那么就會返回304狀態碼,告訴瀏覽器可以使用緩存中的數據,這樣就減少了服務器的數據傳輸壓力。如果數據有更新就會返回200狀態碼,服務區就會返回更新后的資源并且將緩存信息一起返回。跟協商緩存相關的header頭屬性有(ETag/If-Not-Match 、Last-Modified/If-Modified-Since) 請求頭和響應頭需要成對出現。

header屬性可選值優先級優缺點
ETag/If-Not-Match(HTTP/1.1)校驗值1、默認使用hash算法,在分布式環境下可能會出現不同服務器生成的ETag值不一致
2、精確的判斷資源有無被修改,可識別一秒內的修改次數
3、計算ETag需要性能消耗
Last-Modified/If-Modified-Since(HTTP/1.0)GMT時間1、只要資源修改,無論內容有無變化,都會將資源返回客戶端
2、以時刻為標識,無法獲取一秒內的修改變化
3、某些服務器不能準確獲取最后的修改時間

協商緩存的執行流程是這樣的:當瀏覽器第一次向服務器發送請求時,會在響應頭中返回協商緩存的頭屬性:ETag和Last-Modified,其中ETag返回的是一個hash值,Last-Modified返回的是GMT格式的最后修改時間。然后瀏覽器在第二次發送請求的時候,會在請求頭中帶上與ETag對應的If-Not-Match,其值就是響應頭中返回的ETag的值,Last-Modified對應的If-Modified-Since。服務器在接收到兩個參數后會做比較,如果返回的是304狀態碼,則說明請求的資源沒有修改,瀏覽器可以直接在緩存中取數據,否則,服務器會直接返回數據。



注意:
ETag/If-Not-Match是在HTTP/1.1出現的,主要是解決以下問題:

  • Last-Modified標注的是最后修改只能精確到秒級,如果某些文件在1秒鐘以內,被修改多次的話,它將不能準確標注文件的修改時間
  • 如果某些文件被修改了,但是內容并沒有任何變化,而Last-Modified卻改變了,導致文件沒法使用緩存
  • 有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形
  • 私有緩存(瀏覽器級緩存)

    私有緩存只能用于單獨的用戶:(Cache-Control: Private)

    共享緩存(代理級緩存)

    共享緩存可以被多個用戶使用: (Cache-Control: Public)

    HTTP緩存有什么用

  • 減少了冗余的數據傳輸,節省了網絡傳輸的資源消耗
  • 緩解了服務器的壓力,大大提高了網站的性能
  • 加快了客戶端加載網頁的速度
  • 怎么使用HTTP緩存

    一般需要緩存的資源有HTML頁面和其它靜態資源

    HTML頁面緩存的設置主要是在標簽中嵌入 標簽,這種方式只對頁面有效,對頁面上的資源無效

    HTML頁面禁用緩存的設置如下

    <meta http-equiv="pragma" content="no-cache"> // 僅在IE瀏覽器才識別的標簽,不一定會在請求字段加上Pragma, 但的確會讓當前頁面每次都發新請求 <meta http-equiv="cache-control" content="no-cache"> // 其它主流瀏覽器識別的標簽 <meta http-equiv="expires" content="0"> // 僅有IE瀏覽器才識別的標簽,該方式僅僅作為指揮IE緩存時間的標識,你并不能在請求或響應報文中找到Expires字段

    HTML設置緩存如下

    <meta http-equiv="Cache-Control" content="max-age=7200"> // 其它主流瀏覽器識別的標簽 <meta http-equiv="Expires" content="Mon, 20 Aug 2021 23:00:00 GMT"> // 僅有IE瀏覽器才識別的標簽

    靜態資源的緩存一般是在web服務器上配置的,常用的web服務器有: nginx、apache。具體的配置這里不做詳細介紹,大家自行查閱。

    不想使用緩存的幾種方式

  • Ctrl + F5強制刷新,都會直接向服務器提取數據
  • 按F5刷新或瀏覽器的刷新按鈕,默認加上Cache-Control: max-age=0,即會走協商緩存
  • 在IE瀏覽器下不想使用緩存的做法:打開IE,點擊工具欄上的工具 -> Internet選項 -> 常規 -> 瀏覽器歷史記錄,設置,選擇從不,然后保存。最后點擊刪除把Internet臨時文件都刪掉(IE緩存的文件就是Internet臨時文件)。
  • 還有就是上面講到的禁用緩存的做法
  • 對于其他瀏覽器也有清楚緩存的辦法
  • HTTP緩存需要注意的幾點

  • 強緩存情況下,只要緩存還沒過期,就會直接從緩存中取數據,就算服務端有數據變化,也不會從服務端獲取了,這樣就無法獲取到修改后的數據。解決的方法有:在修改后的資源加上隨機數,確保不會從緩存中取。
  • 例如:
    http://www.abc.com/article/a.css?v=2312329
    http://www.abc.com/article/a.2312329.css

  • 盡量減少304的請求,因為我們知道,協商緩存每次都會與后臺服務器進行交互,所以性能上不是很好。從性能上來看盡量多使用強緩存
  • 在FireFox瀏覽器下,使用Cache-Control: no-cache是不生效的,其識別的是no-store。這樣能達到其他瀏覽器使用Cache-Control: no-cache的效果。所以為了兼容FireFox瀏覽器,經常會寫成Cache-Control: no-cache, no-store。
  • 與緩存相關的幾個header屬性有:Vary、Date/Age
  • Vary
    vary本身是“變化”的意思,而在http報文中更趨于是“vary from”(與。。。不同)的含義,它表示服務端會以什么基準字段來區分、篩選緩存版本。
    在服務端有著這么一個地址,如果是IE用戶則返回針對IE開發的內容,否則返回另一個主流瀏覽器版本的內容。
    格式:Vary: User-Agent
    知會代理服務器需要以 User-Agent 這個請求首部字段來區別緩存版本,防止傳遞給客戶端的緩存不正確。

    Date/Age
    響應報文中的 Date 和 Age 字段:區分其收到的資源是否命中了代理服務器的緩存。
    Date 理所當然是原服務器發送該資源響應報文的時間(GMT格式),如果你發現 Date 的時間與“當前時間”差別較大,或者連續F5刷新發現 Date 的值都沒變化,則說明你當前請求是命中了代理服務器的緩存。

    Age 也是響應報文中的首部字段,它表示該文件在代理服務器中存在的時間(秒),如文件被修改或替換,Age會重新由0開始累計。

    瀏覽器緩存

    下面說說最常用的瀏覽器緩存有: cookie、sessionStorage、localStorage這三者的主要特征如下:

    本地緩存容量特征
    cookie4KB1、兼容各種瀏覽器
    2、每次都會和后臺交互
    3、可設置過期時間
    sessionStorage5MB1、H5新增特性,不兼容低版本瀏覽器
    2、本地存儲,不會每次和后臺交互
    3、會話關閉,緩存失效
    localStorage5MB1、H5新增特性,不兼容低版本瀏覽器
    2、本地存儲,不會每次和后臺交互
    3、本地緩存,除非手動刪除,否則一直存在

    總結

    1、對于強緩存,服務器通知瀏覽器一個緩存時間,在緩存時間內,下次請求,直接用緩存,不在時間內,執行協商緩存策略

    2、對于協商緩存,將緩存信息中的ETag和Last-Modified通過請求發送給服務器,由服務器校驗,返回304狀態碼時,瀏覽器直接使用緩存。

    總結

    以上是生活随笔為你收集整理的关于HTTP缓存的故事的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。