#### HTTP緩存
緩存是指可以進行高速[數據](https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE)交換的[存儲器](https://baike.baidu.com/item/%E5%AD%98%E5%82%A8%E5%99%A8),它先于[內存](https://baike.baidu.com/item/%E5%86%85%E5%AD%98)與[CPU](https://baike.baidu.com/item/CPU)交換數據,因此[速率](https://baike.baidu.com/item/%E9%80%9F%E7%8E%87)很快。當某一硬件要讀取數據時,會首先從緩存中查找需要的數據,如果找到了則直接執行,找不到的話則從內存中找。而**http緩存主要針如css,js,圖片等更新頻率不大的靜態文件。**
##### 緩存的優缺點
> 優點
* 加快網頁打開速度
* 減少網絡寬帶的消耗
* 減輕服務器端的壓力
> 缺點
* 服務器緩存中的數據變了,瀏覽器不知道數據是否發生改變。
* 不利于做信息采集
##### 前端緩存

##### HTTP緩存

HTTP緩存規則主要在HTTP協議頭和HTML的meta標簽中定義。他們分別從[**過期機制**](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching_FAQ)和**驗證機制**兩個維度來規定瀏覽器是否可以直接使用緩存中的副本,還是需要去源服務器獲取更新的版本。
##### **過期機制**(緩存副本的有效期,瀏覽器認為緩存生效的情景:)
* 控制頭信息中含有完整的過期時間,并且仍在有效期內;
* 瀏覽器已經使用過這個緩存副本,并在一個會話中已經檢查過的;
##### **驗證機制**
服務器返回資源的時候有時在控制頭信息帶上這個資源的實體標簽Etag(Entity Tag),它可以用來作為瀏覽器再次請求過程的校驗標識。如過發現校驗標識不匹配,說明資源已經被修改或過期,瀏覽器需求重新獲取資源內容。
#### 參數說明
1. **Cache-Control** 和 **Expires**
> **Expires**是HTTP/1.0時添加的,該字段會返回一個時間,`Expires:Thu,31 Dec 2037 23:59:59 GMT`,這個時間代表著資源的失效時間。如果當客戶端時間被修改以后,客戶端和服務器端的時間就會不一致,導致緩存混亂,于是HTTP/1.1提出了**Cache-Control**。
*****
**Cache-Control**存儲的是一個相對時間,`Cache-Control:max-age=<seconds>`,緩存內容將在多少`seconds`后失效,優先級高于**Expires**,主要用于控制網頁緩存。
* **public**:所有內容都將被緩存(客戶端和代理服務器都可緩存)
* **private**:所有內容只有客戶端可以緩存,**Cache-Control的默認值**
* **no-cache**:客戶端緩存內容,但是是否使用緩存則需要經過協商緩存來驗證決定
* **no-store**:所有內容都不會被緩存,即不使用強制緩存,也不使用協商緩存
* **max-age=xxx (xxx is numeric)**:緩存內容將在xxx秒后失效
* **s-maxage**?同 max-age,覆蓋 max-age、Expires,但僅適用于共享緩存,在私有緩存中被忽略。
* **must-revalidate**:緩存在考慮使用一個陳舊的資源時,必須先驗證它的狀態,已過期的緩存將不被使用。
2. **Last-Modify** 和 **If-Modify-Since**
瀏覽器訪問一個資源時,服務器響應瀏覽器的請求,會在`Header`中加入`Last-Modify`,Last-modify是一個時間標識該資源的最后修改時間。
當瀏覽器再次請求該資源時,發送的請求頭中會包含`If-Modify-Since`,該值為緩存之前返回的`Last-Modify`。服務器收到`If-Modify-Since`后,根據資源的最后修改時間判斷是否命中緩存。
```
Response Header
Last-Modify: Sat, 27 Jun 2020 18:00:00 GMT
Request Header
If-Modify-Since: Sat, 27 Jun 2020 18:00:00 GMT
```
3. **ETag** 和 **If-None-Match**
與`Last-Modify/If-Modify-Since`不同的是,`Etag/If-None-Match`返回的是一個校驗碼(ETag: entity tag)。`ETag`可以保證每一個資源是唯一的,資源變化都會導致`ETag`變化。`ETag`值的變更則說明資源狀態已經被修改。服務器根據瀏覽器上發送的`If-None-Match`值來判斷是否命中緩存。
```
Response Header
Etag: W/0QWeW98f8892weqwe
Request Header
If-None-Match: W/0QWeW98f8892weqwe
```
`ETag`對于每一個資源都能生成一個唯一的值,資源變化時`ETag`也會發生變化。`Last-Modified`與`ETag`是可以一起使用的,服務器會優先驗證`ETag`,一致的情況下,才會繼續比對`Last-Modified`。`ETag`的出現解決了`Last-Modify`遇到的一些問題:
* `Last-Modified`最后修改只能精確到秒級,如果一個文件在1秒鐘以內,被修改多次的話,它將不能準確標注文件的修改時間。
* 如果某些文件會被定期生成,當有時內容并沒有任何變化,但`Last-Modified`卻改變了,導致文件沒法使用有效的緩存。
* 有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形。
##### Web Storage兩種機制 及 Cookie
* `sessionStorage` 為給定的源(origin)維持一個獨立的存儲區域,該存儲區域在頁面會話期間可用(即只要瀏覽器處于打開狀態,包括頁面重新加載和恢復)
* `localStorage` 同樣的功能,但是在瀏覽器關閉,然后重新打開后數據仍然存在。
* `Cookie` 是服務器發送到用戶瀏覽器并保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶并發送到服務器上。
```
# put
sessionStorage.setItem('mouse', 'Jerry')
localStorage.setItem('mouse', 'Jerry')
# get
sessionStorage.getItem('mouse')
localStorage.getItem('mouse')
# remove
sessionStorage.removeItem('mouse')
localStorage.removeItem('mouse')
# 清空sessionStorage & localStorage
sessionStorage.clear();
localStorage.clear();
```
###### **Cookie的作用域**
* `Domain`標識指定了哪些主機可以接受Cookie。如果不指定,默認為[當前文檔的主機](https://developer.mozilla.org/en-US/docs/Web/API/Document/location)(**不包含子域名**)。如果指定了`Domain`,則一般包含子域名。
> 例如,如果設置?`Domain=imagicdatatech.com`,則Cookie也包含在子域名中(如`magicadmin.imagicdatatech.com`)
* `Path`標識指定了主機下的哪些路徑可以接受Cookie(該URL路徑必須存在于請求URL中)。以字符`/` 作為路徑分隔符,子路徑也會被匹配。
> 子域下的單點登錄:
假設有兩個域名 `a.imagicdatatech.com`和`b.imageicdatatech.com`,在域名中`a`和`b`都是`www.imagicdatatech.com`的子域名,在`a`或者`b`一方登錄之后,設置`Cookie`的值和`Domain:.imageicdatatech.com`,這樣各個子域都會共享這個`Cookie`的值,再訪問服務器時校驗下`token`的合法性就OK了。
#### 服務器端緩存
* `Combo` 連擊
> `Combo Handler`是Yahoo!開發的一個Apache模塊,它實現了開發人員簡單方便地通過URL來合并JavaScript和CSS文件,從而減少HTTP的請求數。
```
<script src="http://a.tbcdn.cn/??s/kissy/1.2.0/kissy-min.js,p/global/1.0/global-min.js,p/fp/2012/core.js,p/fp/2012/fp/module.js,p/fp/2012/fp/util.js,p/fp/2012/fp/directpromo.js?t=2012062320120712.js" data-fp-timestamp="20120703"></script>
```
> 瀏覽器有**url長度限制**,因此不能無限制的合并資源。
如果用戶在網站內有公共資源的兩個頁面間跳轉訪問,由于兩個頁面的combo的url不一樣導致用戶不能利用瀏覽器緩存來加快對公共資源的訪問速度。如果combo的url中任何一個文件發生改變,都會導致整個url緩存失效,從而導致瀏覽器緩存利用率降低。
* **CDN**
>`CDN`(Content Delivery Network)是指內容分發網絡,也稱為內容傳送網絡。由于CDN是為加快網絡訪問速度而被優化的網絡覆蓋層,因此被形象地稱為“網絡加速器”。其主要作用范圍是用于前端的**靜態資源**加速。`CDN`的緩存配置建議與`HTTP`緩存配置保持一致,其配置會受到`HTTP`緩存的影響,而且各個`CDN`服務商并不完全一致,用到那家就`so`那家~
* 訪問速度(離得最近的資源返回)
* 減輕源站(服務器)的負載壓力
* 跨運營商,可以保證不同網絡中的用戶都能得到良好的訪問質量
* 集群抗攻擊性:主要是降低各種D.D.o.S攻擊對網站的影響
##### **CDN的運作流程**

##### **阿里云CDN解析流程**

*****
1. 當終端用戶(北京)向`www.a.com`下的某資源發起請求時,首先向LDNS(本地DNS)發起域名解析請求。
2. LDNS檢查緩存中是否有`www.a.com`的IP地址記錄。如果有,則直接返回給終端用戶;如果沒有,則向授權DNS查詢。
3. 當授權DNS解析`www.a.com`時,返回域名CNAME`www.a.tbcdn.com`對應IP地址。
4. 域名解析請求發送至阿里云DNS調度系統,并為請求分配最佳節點IP地址。
5. LDNS獲取DNS返回的解析IP地址。
6. 用戶獲取解析IP地址。
7. 用戶向獲取的IP地址發起對該資源的訪問請求。
* 如果該IP地址對應的節點已緩存該資源,則會將數據直接返回給用戶,請求結束。
* 如果該IP地址對應的節點未緩存該資源,則節點向源站發起對該資源的請求。獲取資源后將資源緩存至節點并返回給用戶,請求結束。
* **緩存命中率**
* 對于一個緩存而言,有一點很重要,就是你的緩存到底有沒有用,衡量這個東西的就是緩存命中率。
* **資源預熱**
* 緩存設計中,預熱是很重要的環節,在最初剛開始啟動 CDN 的時候,CDN 上并沒有緩存數據,此刻大量的請求全部打向源站,肯定會把源站打掛,預熱就是事先緩存好熱門數據,這樣在業務上線時,CDN 上已經有所需的數據了。
CDN 這個東西本質是一個緩存,只是這個緩存離你特別的近。
#### 參考鏈接
[單點登錄實現方式](https://blog.csdn.net/koli6678/article/details/80144702)
- 版本控制之Git簡介
- Git工作流程
- Git工作區、暫存區、版本庫
- Git 指令匯總
- Git 忽略文件規則 .gitignore
- pull request
- HTTP簡介
- HTTP - Keep-Alive
- HTTP緩存
- XMLHttpRequest
- Fetch
- 跨域
- HTTP 消息頭
- TCP/IP
- TCP首部
- IP首部
- IP 協議
- TCP/IP漫畫
- 前端開發規范
- 前端開發規范整理
- 前端未來規劃
- HTML思維導圖
- CSS思維導圖
- 布局
- position,float,display的關系和優先級
- line-height、height、font-size
- 移動端適配
- JS 對象
- JS 原型模式 - 創建對象
- JS 預編譯
- 探索JS引擎
- ES