前端面试查漏补缺--(六) 浏览器缓存

浏览器缓存概述

什么是缓存

缓存(和我之前文章所说的前端存储是不一样的!注意区分):
是一种保存资源副本并在下次请求时直接使用该副本的技术。那么浏览器缓存就是浏览器请求网站留下的资源副本。

当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。

缓存的好处

  • 缓解服务器压力(不用每次去请求资源);
  • 提升性能(打开本地资源速度当然比请求回来再打开要快得多);
  • 减少带宽消耗;

缓存的分类

缓存在宏观上可以分成两类:

  • 私有缓存: 只能用于单独用户,最常见的就是浏览器缓存,也是本片重点讲解的.
  • 共享缓存: 够被多个用户使用的缓存,也就是那些能被各级代理的缓存.

浏览器的缓存策略

浏览器对于缓存的处理是根据第一次请求资源时返回的响应头来确定的。

根据响应头,浏览器缓存策略一般分为三种:强缓存,协商缓存启发式缓存

浏览器常见字段和指令

在讲强缓存和协商缓存之前先提前了解以下这几个字段和指令,便于后面理解:

  1. expires: 告知客户端资源缓存失效的绝对时间
  2. last-modified: 资源最后一次修改的时间
  3. Etag: 文件的特殊标识
  4. cache-control:告诉客户端或是服务器如何处理缓存。
  5. private: cache-control里的响应指令.表示客户端可以缓存
  6. public: cache-control里的响应指令.表示客户端和代理服务器都可缓存.如果没有明确指定private,则默认为public。
  7. no-cache: cache-control里的指令.表示需要可以缓存,但每次用应该去向服务器验证缓存是否可用
  8. no-store: cache-control字段里的指令.表示所有内容都不会缓存,强制缓存,对比缓存都不会触发.
  9. max-age=xxx: cache-control字段里的指令.表示缓存的内容将在 xxx 秒后失效

强缓存

强缓存简单理解就是:给浏览器缓存设置过期时间,超过这个时间之后缓存就是过期,浏览器需要重新请求。

强缓存主要是通过http请求头中的Cache-Control和Expires两个字段控制

expires

expires是一个HTTP/1.0的字段,它给浏览器设置了一个绝对时间,当浏览器时间超过这个绝对时间之后,重新向服务器发送请求。

用法:

它描述的是一个绝对时间,用GMT格式的字符串表示

js

复制代码Expires: Wed Feb 20 2019 11:25:41 GMT

也可以在html文件里直接使用:

html

复制代码<meta http-equiv="expires" content="Wed Feb 20 2019 11:25:41 GMT">

弊端:

  • Expires返回的是服务器的时间,但判断的时候用的却是客户端的时间,这就导致Expires很被动,因为用户有可能改变客户端的时间,导致缓存时间判断出错,这也是引入Cache-Control:max-age指令的原因之一。
cache-control: max-age

为了解决expires存在的问题,Http1.1版本中提出了cache-control:max-age,该字段与expires的缓存思路相同,都是设置了一个过期时间,不同的是max-age设置的是相对缓存时间开始往后的多少秒,因此不再受日期不准确情况的影响。

优先级:
在优先级上:max-age>Expires。当两者同时出现在响应头时,Expires将被max-age覆盖.

用法:

js

复制代码Cache-control: max-age=666

表示资源会在 666 秒后过期,需要再次请求。

强缓存在浏览器上的表现
  • Firefox浏览器对强缓存表现为一个灰色的200状态码。
  • Chrome浏览器状态码表现为:200 (from disk cache)或是200 OK (from memory cache)

说明:Chrome会根据本地内存的使用率来决定缓存存放在哪,如果内存使用率很高,放在磁盘里面,磁盘的使用率很高会暂时放在内存里面。这就可以比较合理的解释了为什么同一个资源有时是from memory cache有时是from disk cache的问题了。

但是强制缓存存在一个问题,该缓存方式优先级高,如果在过期时间内缓存的资源在服务器上更新了,客服端不能及时获取最新的资源。这时怎么办?于是就有了协商缓存.

协商缓存

协商缓存解决了无法及时获取更新资源的问题。它利用下面会讲到的两组字段,对资源做标识.然后由服务器做分析,如果资源未更新,则返回304状态码.那么浏览器则会从缓存中读取资源,否则重新请求资源。

协商缓存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对Header来管理的。

Last-Modified与If-Modified-Since
  • 1,浏览器第一次向服务器请求资源,服务器会在返回这个资源的同时,在response的header加上Last-Modified的header,这个header表示这个资源在服务器上的最后修改时间:Last-Modified: Wed Feb 20 2019 14:08:32 GMT
  • 2,浏览器之后再向服务器请求这个资源时,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值:Last-Modified: Wed Feb 20 2019 14:08:32 GMT
  • 3,服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,返回200,就正常返回资源内容。
    • 当服务器返回304 Not Modified的响应时,response的header中不会再添加Last-Modified的header,因为既然资源没有变化,那么Last-Modified也就不会改变,这是服务器返回304时的response header.
  • 4,浏览器收到304的响应后,就会从缓存中加载资源。
  • 5,浏览器收到200的响应后,则从服务器加载新资源时,Last-Modified Header在重新加载的时候会被更新,下次请求时,If-Modified-Since会启用上次返回的Last-Modified值。

弊端:
【Last-Modified,If-Modified-Since】都是根据服务器时间返回的header,一般来说,在没有调整服务器时间和篡改客户端缓存的情况下,这两个header配合起来管理协商缓存是非常可靠的,但是它们是以秒为单位进行更新,如果小于该单位高频进行更新的话,则不适合采用该方法。 这时候协商缓就不那么的可靠了。所以就有了另外一对header来管理协商缓存,这对header就是【ETag、If-None-Match】。

ETag与If-None-Match
  • 1,浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在response的header加上ETag的header,这个header是服务器根据当前请求的资源生成的一个唯一标识,这个唯一标识是一个字符串ETag: shotcat-66666只要资源有变化这个串就不同,跟最后修改时间没有关系,所以能很好的补充Last-Modified的问题.
  • 2,浏览器再次跟服务器请求这个资源时,在request的header上加上If-None-Match的header,这个header的值就是上一次请求时返回的ETag的值If-None-Match: shotcat-66666.
  • 3,服务器再次收到资源请求时,根据浏览器传过来If-None-Match和然后再根据资源生成一个新的ETag,如果这两个值相同就说明资源没有变化,否则就是有变化;如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,则返回200,并正常返回资源内容。与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化
  • 4,浏览器收到304的响应后,就会从缓存中加载资源。
  • 5,浏览器收到200的响应后,则从服务器加载新资源时,ETag在重新加载的时候会被更新,下次请求时,If-None-Match会启用上次返回的ETag值。

Etag和Last-Modified非常相似,都是用来判断一个参数,从而决定是否启用缓存。但是ETag相对于Last-Modified也有其优势,可以更加准确的判断文件内容是否被修改, 从而在实际操作中实用程度也更高,但缺点也很明显,由于需要对资源进行生成标识,性能方面就势必有所牺牲

优先级:
ETag与If-None-Match > Last-Modified与If-Modified-Since, 同时存在时, 前者覆盖后者.

启发式缓存

我跟我们的请求头中确定缓存过期时间的字段一个都没有.例如:

ruby复制代码Age:23146
Cache-Control: public
Date:Tue, 28 Nov 2017 12:26:41 GMT
Last-Modified:Tue, 28 Nov 2017 05:14:02 GMT
Vary:Accept-Encoding

此时则会默认触发浏览器启发式缓存:
浏览器会根据响应头中2个时间字段 Date 和 Last-Modified 之间的时间差值,取其值的10%作为缓存时间周期。

缓存的优先级

在缓存策略上:强缓存>协商缓存>启发式缓存

进一步分析可得出,以下优先级:
Cache-Control > Expires > ETag > Last-Modified

非常注意

其他所有教程都是告诉你浏览器肯定是先检查强缓存,再检查协商缓存!但实际它们都忽略了一点.其实浏览器是先检查Cache-Control,如果为no-store.则浏览器 所有内容都不会缓存,强制缓存,协商缓存统统都不会触发!!!

补充:Pragma

它是HTTP/1.0里面的一个字段,在http1.1已被抛弃,使用Cache-Control替代.但为了做http协议的向下兼容,很多网站依旧会带上这个字段但优先级很高.

测试发现,Chrome和Firefox中Pragma的优先级高于Cache-Control和Expires.

一般可能会这么用:<meta http-equiv="Pragma" content="no-cache">

服务端响应添加’Pragma’: ‘no-cache’,浏览器表现行为和强制刷新类似。

补充: Cache-Control

通过cache-control的指令可以控制告诉客户端或是服务器如何处理缓存。这也是11个字段中指令最多的一个,也是经常被用到的.

请求指令

指令参数说明
no-cache强制源服务器再次验证
no-store不缓存请求或是响应的任何内容
max-age=[秒]缓存时长,单位是秒缓存的时长,也是响应的最大的Age值
min-fresh=[秒]必需期望在指定时间内响应仍然有效
no-transform代理不可更改媒体类型
only-if-cached从缓存获取
cache-extension-新的指令标记(token)

响应指令

指令参数说明
public任意一方都能缓存该资源(客户端、代理服务器等)
private可省略只能特定用户缓存该资源
no-cache可省略缓存前必须先确认其有效性
no-store不缓存请求或响应的任何内容
no-transform代理不可更改媒体类型
must-revalidate可缓存但必须再向源服务器进确认
proxy-revalidate要求中间缓存服务器对缓存的响应有效性再进行确认
max-age=[秒]缓存时长,单位是秒缓存的时长,也是响应的最大的Age值
s-maxage=[秒]必需公共缓存服务器响应的最大Age值
cache-extension-新指令标记(token

请注意no-cache指令很多人误以为是不缓存,这是不准确的,no-cache的意思是可以缓存,但每次用应该去想服务器验证缓存是否可用。no-store才是不缓存内容。 另外部分指令也可以组合使用,比如:

arduino复制代码Cache-Control: max-age=100, must-revalidate, public
复制代码

上面指令的意思是缓存的有效时间为100秒,之后访问需要向源服务器发送请求验证,此缓存可被代理服务器和客户端缓存。

浏览器缓存判断流程

img

HTTP中和缓存相关的首部字段

HTTP报文,主要由以下两部分构成:

  1. 首部(header):包含了很多字段,比如:cookie、缓存、报文大小、报文格式等等);
  2. 主体(body):HTTP请求真正要传输的部分,比如:一个HTML文档,一个js文件;

以上我们知道浏览器对于缓存的处理过程,也简单的提到了几个相关的字段。🤧接下来我们具体看下这几个字段:

1. 通用首部字段

字段名称说明
Cache-Control控制缓存具体的行为
PragmaHTTP1.0时的遗留字段,当值为"no-cache"时强制验证缓存
Date创建报文的日期时间(启发式缓存阶段会用到这个字段)

2. 响应首部字段

字段名称说明
ETag服务器生成资源的唯一标识
Vary代理服务器缓存的管理信息
Age资源在缓存代理中存贮的时长(取决于max-age和s-maxage的大小)

3. 请求首部字段

字段名称说明
If-Match条件请求,携带上一次请求中资源的ETag,服务器根据这个字段判断文件是否有新的修改
If-None-Match和If-Match作用相反,服务器根据这个字段判断文件是否有新的修改
If-Modified-Since比较资源前后两次访问最后的修改时间是否一致
If-Unmodified-Since比较资源前后两次访问最后的修改时间是否一致

4. 实体首部字段

字段名称说明
Expires告知客户端资源缓存失效的绝对时间
Last-Modified资源最后一次修改的时间

用户操作行为对缓存的影响

操作说明
打开新窗口如果指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如:Cache-control: max-age=5 表示当访问此网页后的5秒内不会去再次访问服务器.
在地址栏回车如果值为private或must-revalidate,则只有第一次访问时会访问服务器,以后就不再访问。如果值为no-cache,那么每次都会访问。如果值为max-age,则在过期之前不会重复访问。
按后退按扭如果值为private、must-revalidate、max-age,则不会重访问,而如果为no-cache,则每次都重复访问.
按刷新按扭无论为何值,都会重复访问.(可能返回状态码:200、304,这个不同浏览器处理是不一样的,FireFox正常,Chrome则会启用缓存(200 from cache))
按强制刷新按钮当做首次进入重新请求(返回状态码200)

如果想在浏览器点击“刷新”按钮的时候不让浏览器去发新的验证请求呢?办法找到一个,知乎上面一个回答,在页面加载完毕后通过脚本动态地添加资源:

js复制代码$(window).load(function() {
  	var bg='http://img.infinitynewtab.com/wallpaper/100.jpg';
  	setTimeout(function() {
    	$('#bgOut').css('background-image', 'url('+bg+')');
  	},0);
});

选择合适的缓存策略

对于大部分的场景都可以使用强缓存配合协商缓存解决,但是在一些特殊的地方可能需要选择特殊的缓存策略

  • 对于某些不需要缓存的资源,可以使用 Cache-control: no-store ,表示该资源不需要缓存
  • 对于频繁变动的资源,可以使用 Cache-Control: no-cache 并配合 ETag 使用,表示该资源已被缓存,但是每次都会发送请求询问资源是否更新。
  • 对于代码文件来说,通常使用 Cache-Control: max-age=31536000 并配合策略缓存使用,然后对文件进行指纹处理,一旦文件名变动就会立刻下载新的文件。

题外话

网络安全行业特点

1、就业薪资非常高,涨薪快 2022年猎聘网发布网络安全行业就业薪资行业最高人均33.77万!

img

2、人才缺口大,就业机会多

2019年9月18日《中华人民共和国中央人民政府》官方网站发表:我国网络空间安全人才 需求140万人,而全国各大学校每年培养的人员不到1.5W人。猎聘网《2021年上半年网络安全报告》预测2027年网安人才需求300W,现在从事网络安全行业的从业人员只有10W人。
img

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

关于网络安全学习指南

学习网络安全技术的方法无非三种:

第一种是报网络安全专业,现在叫网络空间安全专业,主要专业课程:程序设计、计算机组成原理原理、数据结构、操作系统原理、数据库系统、 计算机网络、人工智能、自然语言处理、社会计算、网络安全法律法规、网络安全、内容安全、数字取证、机器学习,多媒体技术,信息检索、舆情分析等。

第二种是自学,就是在网上找资源、找教程,或者是想办法认识一-些大佬,抱紧大腿,不过这种方法很耗时间,而且学习没有规划,可能很长一段时间感觉自己没有进步,容易劝退。

第三种就是去找培训。

image.png

接下来,我会教你零基础入门快速入门上手网络安全。

网络安全入门到底是先学编程还是先学计算机基础?这是一个争议比较大的问题,有的人会建议先学编程,而有的人会建议先学计算机基础,其实这都是要学的。而且这些对学习网络安全来说非常重要。但是对于完全零基础的人来说又或者急于转行的人来说,学习编程或者计算机基础对他们来说都有一定的难度,并且花费时间太长。

第一阶段:基础准备 4周~6周

这个阶段是所有准备进入安全行业必学的部分,俗话说:基础不劳,地动山摇
image.png

第二阶段:web渗透

学习基础 时间:1周 ~ 2周:

① 了解基本概念:(SQL注入、XSS、上传、CSRF、一句话木马、等)为之后的WEB渗透测试打下基础。
② 查看一些论坛的一些Web渗透,学一学案例的思路,每一个站点都不一样,所以思路是主要的。
③ 学会提问的艺术,如果遇到不懂得要善于提问。
image.png

配置渗透环境 时间:3周 ~ 4周:

① 了解渗透测试常用的工具,例如(AWVS、SQLMAP、NMAP、BURP、中国菜刀等)。
② 下载这些工具无后门版本并且安装到计算机上。
③ 了解这些工具的使用场景,懂得基本的使用,推荐在Google上查找。

渗透实战操作 时间:约6周:

① 在网上搜索渗透实战案例,深入了解SQL注入、文件上传、解析漏洞等在实战中的使用。
② 自己搭建漏洞环境测试,推荐DWVA,SQLi-labs,Upload-labs,bWAPP。
③ 懂得渗透测试的阶段,每一个阶段需要做那些动作:例如PTES渗透测试执行标准。
④ 深入研究手工SQL注入,寻找绕过waf的方法,制作自己的脚本。
⑤ 研究文件上传的原理,如何进行截断、双重后缀欺骗(IIS、PHP)、解析漏洞利用(IIS、Nignix、Apache)等,参照:上传攻击框架。
⑥ 了解XSS形成原理和种类,在DWVA中进行实践,使用一个含有XSS漏洞的cms,安装安全狗等进行测试。
⑦ 了解一句话木马,并尝试编写过狗一句话。
⑧ 研究在Windows和Linux下的提升权限,Google关键词:提权
image.png
以上就是入门阶段

第三阶段:进阶

已经入门并且找到工作之后又该怎么进阶?详情看下图
image.png

给新手小白的入门建议:
新手入门学习最好还是从视频入手进行学习,视频的浅显易懂相比起晦涩的文字而言更容易吸收,这里我给大家准备了一套网络安全从入门到精通的视频学习资料包免费领取哦!

如果你对网络安全入门感兴趣,那么你需要的话可以在下方扫码领取!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值