ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
#### 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,图片等更新频率不大的静态文件。** ##### 缓存的优缺点 > 优点 * 加快网页打开速度 * 减少网络宽带的消耗 * 减轻服务器端的压力 > 缺点 * 服务器缓存中的数据变了,浏览器不知道数据是否发生改变。 * 不利于做信息采集 ##### 前端缓存 ![](https://img.kancloud.cn/91/86/91860f9219ec5fba958ef5a80519f905_908x399.png) ##### HTTP缓存 ![](https://img.kancloud.cn/0b/5e/0b5e145df9f39c9f9cb2be8e67ec95e1_967x925.png) 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的运作流程** ![](https://img.kancloud.cn/22/b7/22b76d0c7bc7e38f4f96fcd739f38b01_2464x2072.jpg) ##### **阿里云CDN解析流程** ![](https://img.kancloud.cn/21/aa/21aad372bccb53877e7541fc8f5ae14e_893x548.png) ***** 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)