瀏覽器緩存控制詳解(cookie、session、localStorage、Cache-Control等)

摘要:本文將會(huì)詳細(xì)的介紹瀏覽器實(shí)現(xiàn)緩存控制的相關(guān)知識(shí),包括cookie、session、localStorage、Cache-Control、Expires、ETag、Last-Modified等概念。

注:在看本文之前建議可以先看一下網(wǎng)頁(yè)中的登錄注冊(cè)功能是如何實(shí)現(xiàn)的,對(duì)前端和后端的數(shù)據(jù)交互有個(gè)大概的了解。

1、cookie是什么 && cookie能干什么

  • 給cookie一個(gè)定義吧:

Cookie(復(fù)數(shù)形態(tài)Cookies),中文名稱為“小型文本文件”或“小甜餅”。指某些網(wǎng)站為了辨別用戶身份而儲(chǔ)存在用戶本地終端(Client Side)上的數(shù)據(jù)(通常經(jīng)過加密)。 ——摘自維基。

  • 如何通俗的解釋:

    1. Cookie 是瀏覽器訪問服務(wù)器后,服務(wù)器傳給瀏覽器的一段數(shù)據(jù)。
    2. 瀏覽器需要保存這段數(shù)據(jù),不得輕易刪除。
    3. 此后每次瀏覽器訪問該服務(wù)器,都必須帶上這段數(shù)據(jù)。
  • 所以就能得出cookie的特點(diǎn):

    1. 服務(wù)器通過設(shè)置Set-Cookie 響應(yīng)頭來(lái)設(shè)置 cookie
    2. 瀏覽器得到 cookie 后,每次同源的請(qǐng)求的請(qǐng)求頭都會(huì)帶上 cookie
    3. 服務(wù)器讀取 cookie 就知道了登錄用戶的信息(如賬戶名等)
    4. cookie 實(shí)際上存儲(chǔ)在本地計(jì)算機(jī)的硬盤里
    5. cookie 的最大儲(chǔ)存量一般只有4K
  • 那么cookie有哪些缺點(diǎn)呢:

    1. Cookie很容易被用戶篡改( Session 可以解決這個(gè)問題,防止用戶篡改)
    2. Cookie 的默認(rèn)有效期理論上在用戶關(guān)閉頁(yè)面后就失效,實(shí)際上在在20分鐘左右,不同瀏覽器策略不同。但是后端可以強(qiáng)制設(shè)置有效期(如何設(shè)置見下文)。
    3. Cookie 也有一定的同源策略,不過跟 AJAX 的同源策略稍微有些不同。如:
      • 當(dāng)請(qǐng)求 qq.com 下的資源時(shí),瀏覽器會(huì)默認(rèn)帶上 qq.com 對(duì)應(yīng)的 Cookie,不會(huì)帶上 baidu.com 對(duì)應(yīng)的 Cookie
      • 當(dāng)請(qǐng)求 v.qq.com 下的資源時(shí),瀏覽器不僅會(huì)帶上 v.qq.com 的Cookie,還會(huì)帶上 qq.com 的 Cookie
      • 另外 Cookie 還可以根據(jù)路徑做限制,請(qǐng)自行了解,這個(gè)功能用得比較少。
  • 有了Cookie,我們就可以實(shí)現(xiàn)這兩件事 :

    • 第一個(gè)作用是識(shí)別用戶身份。如:
      比如用戶 A 用瀏覽器訪問了http://a.com,那么http://a.com 的服務(wù)器就會(huì)立刻給 A 返回一段數(shù)據(jù)「uid=1」(這就是 Cookie)。當(dāng) A 再次訪問 http://a.com的其他頁(yè)面時(shí),就會(huì)附帶上「uid=1」這段數(shù)據(jù)。這樣服務(wù)端就知道 A 是誰(shuí)了。

    • 第二個(gè)作用是記錄歷史。如:
      假設(shè) http://a.com 是一個(gè)購(gòu)物網(wǎng)站,當(dāng) A 在上面將商品 B1 、B2 加入購(gòu)物車時(shí),JS 可以改寫 Cookie,改為「uid=1; cart=B1,B2」,表示購(gòu)物車?yán)镉?B1 和 B2 兩樣商品了。這樣一來(lái),當(dāng)用戶關(guān)閉網(wǎng)頁(yè),過三天再打開網(wǎng)頁(yè)的時(shí)候,依然可以看到 B1 、B2躺在購(gòu)物車?yán)?,因?yàn)闉g覽器并不會(huì)無(wú)緣無(wú)故地刪除這個(gè) Cookie。

    • (需要注意的是:上面的例子只是為了讓大家了解 Cookie 的作用而構(gòu)想出來(lái)的,實(shí)際的網(wǎng)站使用 Cookie 時(shí)會(huì)更謹(jǐn)慎一些。為什么要非常謹(jǐn)慎的使用cookie請(qǐng)從下文尋找答案。)

  • 那么我們?nèi)绾卧O(shè)置cookie呢:
    其實(shí)只要一句話:在響應(yīng)頭中設(shè)置Set-Cookie即可,詳見Set-Cookie MDN 。具體參數(shù)如下:

    • Set-Cookie: <cookie-name>=<cookie-value>
      普通的cookie,所有參數(shù)默認(rèn)
    • Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
      cookie 的最長(zhǎng)有效時(shí)間,形式為符合 HTTP-date 規(guī)范的時(shí)間戳。
    • Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
      在 cookie 失效之前需要經(jīng)過的秒數(shù)。一位或多位非零(1-9)數(shù)字。假如二者 (指 Expires 和Max-Age) 均存在,那么 Max-Age 優(yōu)先級(jí)更高。
    • Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
      指定 cookie 可以送達(dá)的主機(jī)名。假如沒有指定,那么默認(rèn)值為當(dāng)前文檔訪問地址中的主機(jī)部分(但是不包含子域名)。與之前的規(guī)范不同的是,域名之前的點(diǎn)號(hào)會(huì)被忽略。假如指定了域名,那么相當(dāng)于各個(gè)子域名也包含在內(nèi)了。
    • Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
      指定一個(gè) URL 路徑,這個(gè)路徑必須出現(xiàn)在要請(qǐng)求的資源的路徑中才可以發(fā)送 Cookie 首部。
    • Set-Cookie: <cookie-name>=<cookie-value>; Secure
      一個(gè)帶有安全屬性的 cookie 只有在請(qǐng)求使用SSL和HTTPS協(xié)議的時(shí)候才會(huì)被發(fā)送到服務(wù)器。(注意:非安全站點(diǎn)(http:)已經(jīng)不能再在 cookie 中設(shè)置 secure 指令了)
    • Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
      設(shè)置了 HttpOnly 屬性的 cookie 不能使用 JavaScript 經(jīng)由 Document.cookie 屬性、XMLHttpRequestRequestAPIs 進(jìn)行訪問,以防范跨站腳本攻擊(XSS)。
    • Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict
    • Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax
      上面兩個(gè)允許服務(wù)器設(shè)定一則 cookie 不隨著跨域請(qǐng)求一起發(fā)送,這樣可以在一定程度上防范跨站請(qǐng)求偽造攻擊(CSRF)。
  • 如何刪除cookie
    通過設(shè)置cookie的有效期在當(dāng)前時(shí)間之前,就可以刪除cookie啦

     var delete_cookie = function(name) {
         document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;';
     };
    
  • cookie 的 HttpOnly 屬性
    為避免跨域腳本 (XSS)攻擊,通過JavaScript的 Document.cookie API無(wú)法訪問帶有 HttpOnly 標(biāo)記的Cookie,它們只應(yīng)該發(fā)送給服務(wù)端。如果包含服務(wù)端 Session 信息的 Cookie 不想被客戶端 JavaScript 腳本調(diào)用,那么就應(yīng)該為其設(shè)置 HttpOnly 標(biāo)記。

    Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
    

2、使用session保存信息

  • 先舉個(gè)例子看如何使用session
    之前的寫法:直接將數(shù)據(jù)放到cookie里面:
    response.setHeader('Set-Cookie', `login_email=${email}`)
    
    這樣寫一來(lái)會(huì)暴露用戶的個(gè)人信息,二來(lái)用戶可以直接通過瀏覽器修改cookie,極有可能獲取到別人的用戶信息,極不安全。因此出現(xiàn)了下面的使用session的操作:
    let sessions = {}
    let sessionId = Math.random() * 10000 // 設(shè)置sessionId 為一個(gè)隨機(jī)數(shù)
    sessions[sessionId] = {login_email:email} // 將email 存儲(chǔ)在sessions這個(gè)對(duì)象中
    response.setHeader('Set-Cookie', `sessionId = ${sessionId}`) 
    // cookie中存儲(chǔ)的是 sessionId 這個(gè)隨機(jī)數(shù)
    
    首先來(lái)解釋一下上面的代碼:即設(shè)置cookie的中存儲(chǔ)的值為一個(gè)隨機(jī)數(shù),當(dāng)后臺(tái)獲取到cookie時(shí),就可以獲取到該隨機(jī)數(shù)并在sessions這個(gè)對(duì)象中查找key為這個(gè)隨機(jī)數(shù)的value,即可知道用戶的郵箱是什么 。如圖所示,此時(shí)的響應(yīng)頭是這樣的:
  • 那么究竟如何定義session呢:
    首先我們得知道session的本質(zhì):就是存儲(chǔ)在服務(wù)器上的一個(gè)哈希表。

    1. sessionID(隨機(jī)數(shù)) 通過 Cookie 發(fā)給客戶端
    2. 客戶端訪問服務(wù)器時(shí),服務(wù)器讀取 sessionID
    3. 服務(wù)器有一塊內(nèi)存(哈希表)保存了所有 session
    4. 通過sessionID 后臺(tái)可以得到對(duì)應(yīng)用戶的隱私信息,如 id,email
    5. 這塊內(nèi)存(哈希表)就是服務(wù)器上的所有 session
  • 那么session相對(duì)于cookie就沒有缺點(diǎn)了嗎?
    很明顯,答案是否定的。session最大的缺點(diǎn)就是占內(nèi)存,如果你的用戶量非常大,服務(wù)器就需要足夠的容量來(lái)存儲(chǔ)數(shù)據(jù)。

  • 不基于cookie能否實(shí)現(xiàn)session呢
    答案是肯定的,可以通過設(shè)置網(wǎng)址的查詢參數(shù) + localStorage 來(lái)達(dá)成目的。具體過程如下:

    1. 后端待用戶登陸后設(shè)置他的sessionID,但不把它放在 cookie 里,而是將信息通過響應(yīng)體傳JSON給前端。
    2. 前端拿到響應(yīng)體中的JSON后將其轉(zhuǎn)換成對(duì)象(JSON.parse
    3. 將從JSON中獲取到的數(shù)據(jù)(如 sessionID)放在 localStorage 里面(localStorage里的數(shù)據(jù)目前暫時(shí)用不到)
    4. 以后跳轉(zhuǎn)到其他頁(yè)面(如首頁(yè))時(shí),將 sessionID 放在 URL 的查詢參數(shù)里(如:window.location.href = '/?sessionId=object.sessionId'
    5. 那么進(jìn)入首頁(yè)后,該頁(yè)面的 URL 的查詢參數(shù)就帶上了你的sessionID
    6. 后端通過在用戶訪問首頁(yè)時(shí),傳到服務(wù)器的 URL ,來(lái)獲取到查詢參數(shù),從而獲取到用戶的 sessionID,然后在數(shù)據(jù)庫(kù)中查到sessionID對(duì)應(yīng)的信息就可以知道用戶是誰(shuí)。

3、localStorage是什么 & localStorage 怎么用

localStorage 是HTML5 技術(shù)提供的api ,是window對(duì)象下的一個(gè)方法(window.localStorage)。

localStorage 的實(shí)質(zhì)是一個(gè)存儲(chǔ)在計(jì)算機(jī)本地的哈希表。

  • localStorage常用的api

    • localStorage.setItem('myCat', 'Tom')
      訪問當(dāng)前域名下的本地 Storage 對(duì)象,并增加了一個(gè)數(shù)據(jù)項(xiàng)通過使用Storage.setItem() 作為 Storage 接口的方法,接受一個(gè)鍵名和值作為參數(shù),將會(huì)把鍵名添加到存儲(chǔ)中,如果鍵名已存在,則更新其對(duì)應(yīng)的值。
    • let cat = localStorage.getItem('myCat')
      該語(yǔ)法用于讀取 localStorage 項(xiàng)
    • localStorage.removeItem('myCat')
      該語(yǔ)法用于移除 localStorage 項(xiàng)
    • localStorage.clear()
      該語(yǔ)法用于移除所有的 localStorage 項(xiàng)
  • 需要注意的是:localStorage 只能存 string,所以如果想存Object,就需要用JSON來(lái)存,舉個(gè)例子:
    localStorage.setItem('jsonObj',JSON.stringify({name:'obj'}))
    然后如果想要解析這個(gè) JSON 將其轉(zhuǎn)換成對(duì)象可以使用 JSON.parse()

  • 那么localStorage怎么使用呢:

    • 首先我們需要知道JS中的變量有這樣的問題:變量只在當(dāng)前的會(huì)話期內(nèi)有效。即只要刷新頁(yè)面,之前存儲(chǔ)的變量就被回收了。那么我們?nèi)绾巫屩八鎯?chǔ)的變量在刷新頁(yè)面之后還存在呢,所以就有了localStorage 來(lái)解決這個(gè)需求。
    • 來(lái)看一個(gè)小demo,這個(gè)demo通過使用 localStorage 完成了變量的持久化存儲(chǔ),因?yàn)閘ocalStorage實(shí)際上是存儲(chǔ)在本地計(jì)算機(jī)中的,不會(huì)因?yàn)轫?yè)面刷新就導(dǎo)致變量被回收。
      let a = localStorage.getItem('a')
      if(!a){
        a = 0
      }esle{
        a = parseInt(a,10) + 1 // 如果不進(jìn)行轉(zhuǎn)換,將會(huì)變成字符串的相加
      }
      console.log(a)
      localStorage.setItem('a',a)
      // 每次刷新頁(yè)面 ,a 的值都會(huì)加 1
      
    • 常見的使用情景:用戶第一次進(jìn)入頁(yè)面時(shí)提示用戶一些信息,第二次進(jìn)入以后就不再提示。 示例代碼如下:
      let already = localStorage.getItem('isPrompt')
      if(!already){
        alert('我們的頁(yè)面改版啦')
        localStorage.setItem('isPrompt', true)
      }esle{
         // 已經(jīng)提示了就什么也不做
      }
      
  • localStorage的特點(diǎn)

    1. localStorage 與 HTTP 無(wú)關(guān)
    2. HTTP 不會(huì)帶上 localStorage 的值
    3. 只有相同域名的頁(yè)面才能互相讀取 localStorage(遵循同源策略)
    4. 每個(gè)域名 localStorage 最大存儲(chǔ)量為 5Mb 左右(每個(gè)瀏覽器不一樣)
    5. 常用場(chǎng)景:記錄有沒有提示過用戶(記錄一些不敏感的信息)
    6. localStorage 理論上永久有效,除非用戶清理緩存,無(wú)法設(shè)置過期時(shí)間
  • sessionStorage 和 localStorage 有什么關(guān)系和區(qū)別

    • 上一條記錄的 localStorage 的特點(diǎn),1~4條二者都有。
    • 區(qū)別:sessionStorage 在用戶關(guān)閉頁(yè)面后(即 session 結(jié)束后或者說會(huì)話結(jié)束后)就失效,而且沒辦法控制;而 localStorage 理論上永久有效。
    • sessionStorage 的 api 和 localStorage 完全一樣。如setItem()getItem()、remove()clear()

4、關(guān)于上面的概念需要注意的事情

  • cookie 和 session 有什么關(guān)系:
    答:一般來(lái)說 cookie 是基于 session 實(shí)現(xiàn)的。cookie是存在客戶端本地的,而session是保存在服務(wù)器上的。

  • cookie 和 localStorage 的區(qū)別是什么
    答:cookie 每次請(qǐng)求會(huì)被帶給服務(wù)器,而 localStorage不會(huì);cookie的最大儲(chǔ)存量一般只有4k,而localStorage 一般有5Mb ;cookie的有效期一般在用戶關(guān)閉頁(yè)面后就失效,而localStorage理論上永久有效。

  • 可能你就要問了,看起來(lái)cookie 和 localStorage 幾乎沒有關(guān)系,為什么要放在一起比較?
    這是由歷史原因的:localStorage 是新API,在它出現(xiàn)以前,之前的前端如何實(shí)現(xiàn)跨頁(yè)面的數(shù)據(jù)持久化存儲(chǔ)呢?只能通過cookie ,要知道cookie 和 localStorage 都是存放在計(jì)算機(jī)本地,所以當(dāng)時(shí)很多程序員都把數(shù)據(jù)放在cookie里,但是有個(gè)問題,你所有存在 cookie里面的東西,每次請(qǐng)求都會(huì)帶到服務(wù)器里面去,如果cookie里面放的東西太多,那么每次請(qǐng)求就要花費(fèi)更多的時(shí)間。所以要達(dá)到跨頁(yè)面的數(shù)據(jù)持久化存儲(chǔ),最優(yōu)解就是使用 localStorage。

  • 前端永遠(yuǎn)不要讀或者寫cookie,讀寫cookie一系列的操作是后端需要完成的工作。(這里的前后端指的是代碼上的分離而不是人員上的分離)

5、HTTP緩存 & Cache-Control 緩存控制

需要提一句的是:緩存控制其實(shí)也是前端性能優(yōu)化的一部分,所以這一點(diǎn)其實(shí)很值得關(guān)注。

緩存控制的使用場(chǎng)景:一些網(wǎng)站需要加載的資源很多,導(dǎo)致每次刷新頁(yè)面速度都非常都慢,那么該如何加快請(qǐng)求速度,緩存控制就應(yīng)運(yùn)而生。

Cache-Control 通用消息頭被用于在http 請(qǐng)求和響應(yīng)中通過指定指令來(lái)實(shí)現(xiàn)緩存機(jī)制。緩存指令是單向的, 這意味著在請(qǐng)求設(shè)置的指令,在響應(yīng)中不一定包含相同的指令。

最常用的響應(yīng)指令:Cache-Control: max-age=<seconds>

  • 設(shè)置緩存存儲(chǔ)的最大周期,超過這個(gè)時(shí)間緩存被認(rèn)為過期(單位秒)。與Expires相反,時(shí)間是相對(duì)于請(qǐng)求的時(shí)間。即在設(shè)置的時(shí)間內(nèi),請(qǐng)求相同的URL將不會(huì)把請(qǐng)求發(fā)送到服務(wù)器,瀏覽器會(huì)阻斷這個(gè)請(qǐng)求(即這個(gè)請(qǐng)求實(shí)際并沒有發(fā)送出去),然后然后之間展示緩存過的上一次的數(shù)據(jù)(存儲(chǔ)在本地的硬盤或內(nèi)存)。實(shí)際開發(fā)中,我們一般設(shè)置為一年31536000秒以上
  • 需要注意的是:一般首頁(yè)(甚至包括所有的html頁(yè)面)不應(yīng)該設(shè)置緩存(chrome瀏覽器甚至?xí)苯咏眠@個(gè)設(shè)置,也就是說你給首頁(yè)設(shè)置Cache-Control也不會(huì)生效)。因?yàn)槿绻氵B首頁(yè)都設(shè)置了緩存,用戶即使刷新頁(yè)面,也不會(huì)向服務(wù)器發(fā)送任何請(qǐng)求,那么如果你的代碼更新了,用戶在緩存期間將始終無(wú)法獲取到最新的版本。
  • 實(shí)際開發(fā)中的使用:html頁(yè)面不設(shè)置Cache-Control,其他資源Cache-Control設(shè)置一年以上,如果代碼更新(比如js或css),該資源的請(qǐng)求的url的查詢參數(shù)加上一個(gè)版本號(hào),或者文件名后加隨機(jī)數(shù)即可。也就是說,只要你的請(qǐng)求的url有一點(diǎn)點(diǎn)不一樣,就不會(huì)使用緩存

6、Expires 是什么 & 有什么不好的地方

  • Expires 也是用來(lái)控制緩存的,但是現(xiàn)在在開發(fā)中,優(yōu)先使用Cache-Control
    Expires 響應(yīng)頭包含日期/時(shí)間, 即在此時(shí)候之后,緩存過期。

  • 如何使用Expires呢:
    設(shè)置響應(yīng)頭,如:Expires:"Wed, 22 Aug 2018 07:43:17 GMT"
    后面接的是格林尼治時(shí)間。當(dāng)過了設(shè)置的時(shí)間后緩存就過期了。

  • 所以 ExpiresCache-Control的區(qū)別就是:前者設(shè)置的是什么時(shí)候過期,后者設(shè)置的是過了多久過期。

  • 需要注意的是:如果在 Cache-Control 響應(yīng)頭設(shè)置了 "max-age" 或者 "s-max-age" 指令,那么 Expires 頭會(huì)被忽略。那么為什么 Cache-Control 優(yōu)先級(jí)比Expire 高呢?

  • 因?yàn)?Cache-Control 相對(duì)于 Expires 是個(gè)更新的技術(shù), 而且使用 Expires 是存在bug 的。

  • Expires 的bug:時(shí)間使用的是計(jì)算機(jī)本地的時(shí)間,如果某一天計(jì)算機(jī)時(shí)間錯(cuò)亂,本地時(shí)間一直在你設(shè)置的時(shí)間之后,那么他就永遠(yuǎn)使用不了緩存。

7、ETag 是什么 & MD5 是什么

首先,Etag 是用來(lái)給文件一個(gè)版本號(hào)的。

那么我們先來(lái)了解一下MD5 。MD5是一個(gè)消息摘要算法。MD5 的常見使用場(chǎng)景:你在網(wǎng)上下載一個(gè)很大的文件,下載過程中你怎么知道自己下載的對(duì)不對(duì)呢?所以MD5 就是為了這種情景而生的。即網(wǎng)上的文件除了有資源本身外,還會(huì)有一個(gè)MD5值,然后你下載到本地后的文件也可以算出一個(gè)MD5 值,然后二者對(duì)比,如果完全相同則說明下的文件是正確的。

Etag 的使用場(chǎng)景:

  1. 后端算出資源的MD5值,將其設(shè)置到響應(yīng)頭的Etag里,如:
    Etag:"33a64df551425fcc55e4d42a148795d9f25f89d4"
  2. 然后下一次請(qǐng)求時(shí),里面這個(gè)資源的請(qǐng)求頭就多了一個(gè)值:
    If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  3. 后端就有如下設(shè)置:
    如果請(qǐng)求頭的If-None-Match中的值和資源的MD5一樣,說明資源是最新的,不需要下載,即可以返回304狀態(tài)碼( Not Modified),然后在此分支下就不用設(shè)置響應(yīng)體了。
  4. 如果MD5的值不一樣,說明你的資源需要更新,此時(shí)再返回最新的資源作為響應(yīng)體。

Etag 與 Cache-Control 的區(qū)別

  • Cache-Control 直接不會(huì)發(fā)請(qǐng)求,只要url一樣,直接使用緩存了的數(shù)據(jù)
  • Etag 則每一次都會(huì)請(qǐng)求,只不過如果資源的MD5一樣,就不下載

8、Last-Modified 是什么 & 使用過程是怎么樣的

Last-Modified 是一個(gè)響應(yīng)首部,其中包含源頭服務(wù)器認(rèn)定的資源做出修改的日期及時(shí)間。 它通常被用作一個(gè)驗(yàn)證器來(lái)判斷接收到的或者存儲(chǔ)的資源是否彼此一致。由于精確度比 ETag 要低,所以這是一個(gè)備用機(jī)制。包含有 If-Modified-SinceIf-Unmodified-Since首部的條件請(qǐng)求會(huì)使用這個(gè)字段。

使用過程:

  1. 在瀏覽器第一次請(qǐng)求某一個(gè)URL時(shí),服務(wù)器端的返回狀態(tài)會(huì)是200,內(nèi)容是你請(qǐng)求的資源,同時(shí)有一個(gè)Last-Modified的屬性標(biāo)記在響應(yīng)頭里,此文件在服務(wù)期端最后被修改的時(shí)間,格式類似這樣:
    Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT
  2. 客戶端第二次請(qǐng)求此URL時(shí),根據(jù)HTTP協(xié)議的規(guī)定,瀏覽器會(huì)向服務(wù)器傳送If-Modified-Since請(qǐng)求頭,詢問該時(shí)間之后文件是否有被修改過:
    If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT
  3. 如果服務(wù)器端的資源沒有變化,則自動(dòng)返回HTTP 304(NotChanged.)狀態(tài)碼,內(nèi)容為空,這樣就節(jié)省了傳輸數(shù)據(jù)量。當(dāng)服務(wù)器端代碼發(fā)生改變或者重啟服務(wù)器時(shí),則重新發(fā)出資源,返回和第一次請(qǐng)求時(shí)類似。從而保證不向客戶端重復(fù)發(fā)出資源,也保證當(dāng)服務(wù)器有變化時(shí),客戶端能夠得到最新的資源。

(END)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容