缓存是用来做什么的?
从我们在浏览器输入地址再按下回车以后,浏览器会向服务器依次进行DNS查询、初始化链接、发送请求以及等待服务器响应,这些都会耗费一定的时间。这些过程结束之后,就会从服务器上下载相应的内容,这也会耗费一定的时间。但是,如果我这次要下载的内容和上一次一模一样的话,那就可以从缓存中获取这些内容,不必再从服务器上下载,进而节约内容的下载时间,这就是缓存的作用。设置Cache-Control
这是一种比较老的设置缓存的方法,在服务端对相应文件(比如:example.css)的响应头设置Cache-Control:public,max-age=3600,这样,以后在请求example.css时,就不会从服务器上下载文件而是从缓存里拿文件了。而缓存的时间就是上面设置的3600秒,在这3600秒之内浏览器都只从缓存里读取example.css,过了3600秒才会再次从服务器上读取文件。问题:如果我的example.css在这3600秒之内发生变化了怎么办?如何让变化了的example.css被下载而不是从缓存当中读取旧的example.css呢?
首先,默记以下真理:缓存都是依据url来实现的。相应的,只要把example.css改为example_1.css再重新设置下服务器路径,那么浏览器就会根据新的url来请求相应的文件,而不会再从缓存中拿了。当然,这是非常旧的方法,五年前的前端是这么干的。至少有一个文件不应该被缓存
如果html文件被缓存了,那么依托这个html文件的其它css和JS文件即便更改了路径也无法请求到了,这就要求这个html文件不应该被缓存。而浏览器对于用户发的第一个请求默认不缓存。这样的话,其它的文件有更改了才会有被从服务器读取的机会。Expires
一般不和Cache-Control共用。不推荐使用expires。它同样是在响应头里添加一个Expires,它的值是一个格林梅治时间,在这个时间之前会一直缓存,这个时间之后会再次从服务器上下载相应的文件。
Expires的问题及与Cache-Control的区别:Expires设置的一个绝对时间,比如说设置的缓存过期时间为2018年1月1日,而它的对比时间是用户的本地时间。如果用户把自己电脑的时钟调快了一年的话,那这个缓存时间就无效了。相对的,Cache-Control设置的相对时间,即当内容下载之后的时间,不会受到用户本地时间的影响。
Last-modified
不推荐使用。它设置的是一个资源的最后修改时间,举个例子,一个资源的Last-modified时间为2016年8月1日,而今天的时间为2017年8月1日,当浏览器读取到这个资源的最后修改时间时,它就会认为,既然这个资源过去一年都没有修改过,那么将来可能也不会修改,于是就会给一个启发式的缓存时间,一般来说是Last-modified值距离现在时间的10%;ETag
想理解ETag就需要首先理解md5。md5是一种算法,它接受一个输入,是任意字符串,输出是一个32位的字符串。它的经常用来定两个不知道内容的东西是否是相等的。
当在响应头中使用了ETag时,资源会被哈希(可以是md5也可以是其它算法),这个哈希值是唯一的。它和内容一样会返回给浏览器,当浏览器下次再请求这个资源时,之前的哈希值会在请求头if-none-match一同发送给服务器,服务器会再计算一次这个资源的哈希值,并且把它和浏览器请求过来的if-none-match值进行比对,如果二者是一样的,这就表示这个资源没有更改过,那就从缓存中直接拿就行,如果值不一样的话,那就表示这个资源有更新,那就从服务器下载这个资源的更新版本。
因为所有文件都只有一个哈希值,一个文件在被修改前后,它的哈希值是不一样的。