文章目录
缓存策略
Doctype
< Doctype > 标签申明位于文档的开头,用于告诉浏览器以什么样的方式来渲染页面,有混杂模式和严格模式两种
混杂模式向后兼容,模拟老浏览器,防止浏览器版本过旧不兼容页面
严格模式是将JS和排版以浏览器最高的标准运行
强缓存和协商缓存
服务器上的数据是会有更新的,我们不能一直使用浏览器的本地缓存,这样就只能一直使用旧数据。我们希望当服务器的数据发生更新时,浏览器会请求更新数据,如果服务器上的数据没有更新我们就使用本地数据,这样能节省因网络请求而产生的资源浪费。
明确两点:
1、浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
2、浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中
1.强缓存(Cache-control)
关键词:不发送请求
强缓存就是强制缓存,直接读取浏览器缓存。如果在服务器响应的头部字段中设置了cache-control:max-age=xxx,public/private/immutable,都有强制缓存,只要缓存的有效时间(xxx秒)没过,就直接读取浏览器缓存。如果是用户主动刷新页面,会发起http请求资源,有额外的请求消耗,但是如果设置的是immutable即使用户刷新也直接读取浏览器缓存。
强缓存有两种策略,对应HTTP1.0,和HTTP1.1。
Expires策略(HTTP1.0)
Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
Expires设置失效时间,精确到时分秒。 不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。
Cache-control策略(重点关注)
Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
http协议头Cache-Control : 值可以是public、private、no-cache、no-
store、no-transform、must-revalidate、proxy-revalidate、max-age
2. 协商缓存(Last-Modifined)
关键词:
协商缓存:200,304,发送请求
Last-Modifined -> If-Modified-Since 修改时间
Etag -> If-None-Match 服务器唯一标识
当浏览器请求资源时发现缓存过期,就会去请求服务器进行协商缓存。在之前的服务器响应的头部中,还有两个字段与协商缓存有关
etag: ‘5c20abbd-e2e8’
last-modified: Mon, 24 Dec 2018 09:49:49 GMT
etag是一个文件hash,每个文件唯一。
last-modified是文件最后更新的时间。在协商缓存时浏览器的请求会携带这两个字段,服务器会根据这两个标识对比判断文件是否更新,如果发生了更新就会返回200状态码,和第一次请求资源一样;如果没有更新就会返回304,调用浏览器缓存。
缓存:cookie、session、webStorage
1. cookie,sessionStorage和localStorage
相同点:cookie,sessionStorage和localStorage都是存储在浏览器端的。
不同点:
- cookie数据始终在浏览器请求中被携带,在浏览器端和服务器端来回传递的;sessStorage和localStorage同属于webStorage,仅在本地保存,不会传递到服务器端
- 存活时间:cookie在设置的存活时间之前一直有效,sessionStorage在浏览器窗口关闭之前一直有效,localStorage始终有效
- 存储大小:cookie只有4KB,sessStorage和localStorage存储空间大一些(大概5Mb左右)
- 作用域:sessionStorage不在不同的浏览器窗口中共享,即使同一个页面,
而cookie和localStorage在同源窗口(协议、域名、端口相同)中均共享
2. cookie和session
cookie数据存储在客户端,session数据存储在服务器。
相比session,cookie不是很安全,别人可以分析存储在本地的cookie并进行cookie诈骗;
而session,当访问增多时,会比较占用服务器性能。
总结:
-
Cookie受到浏览器同源策略的限制,A页面的Cookie无法被B页面的Cookie访问和操作。
-
Cookie最大存储容量一般为4KB,由服务器生成,在HTTP报文首部设置 Set-Cookie可以指定生成Cookie的内容和生命周期,保存在硬盘中;如果没有设置过期时间就是会话cookie,保存在内存中,关闭浏览器窗口就会失效。
即cookie有两种。一种放在硬盘,有生命周期。另一种放在内存(会话cookie),关闭浏览器就失效。
-
Cookie存储在浏览器端,由于每次发送HTTP请求默认会把Cookie附到HTTP首部上去,所以Cookie主要用来身份认证,而不用来存储其他信息,防止HTTP报文过大。
-
Session存储在服务器,主要与Cookie配合使用完成身份认证和状态保持的功能。
所有,只拥有Cookie或Session其中一项,无法完成身份认证和状态保持的功能。
- 对Cookie和Session实现的身份认证和状态保持功能做一个举例。
假设现在有一个学生信息管理系统,此时数据库已经有学生的相关信息(账号、密码、个人信息等等)。
然后当学生登录这个系统,通过POST请求把用户的账户密码发送到后台服务器。当后台服务器接收到这些参数的时候,会跟数据库保存的记录进行匹配。
一旦匹配成功,也就是用户的账号密码都正确的情况下,这个时候后台服务器会生成Session(一个为客户端开辟存储空间,用来保存会话的状态信息),并生成一个相应的SessionID,可以是用户名或者其他能够唯一标识用户的字段。然后后台服务器会返回响应告知客户端登录成功,可以进行后续的操作。此时,后台服务器会在HTTP响应报文中添加一个字段
Set-Cookie,它的值是当前Session的SessionID,(这个SessionID是指向我们当前的那个Session的,在Node的Express中express-session会封装好这个过程)当然还会设置Cookie的其他属性,比如说过期时间
Expires等等。当浏览器接收到这个HTTP响应报文的时候,就会在本地设置一个Cookie,它的过期时间由响应报文中 Set-Cookie中的
Expires字段的值决定,如果为空,则关闭浏览器(即会话结束时)后失效。之后,每次向后台服务器发送请求的时候,浏览器默认会把这个Cookie加在HTTP请求报文的Cookie中。这样,每次后台服务器接收到请求的时候,会根据Cookie中的SessionID去找到我们的Session。
假如这个SessionID映射得到Session,那么这个时候说明浏览器是已经登录过了。于是,就可以进行后续的一些相关的操作。
另外,值得一提的是,Session机制决定了当前客户只会获取到自己的Session,而不会获取到别人的Session。各客户的Session也彼此独立,互不可见。也就是说,当多个客户端执行程序时,服务器会保存多个客户端的Session。获取Session的时候也不需要声明获取谁的Session。
选自:面经复习-浏览器缓存和304
多个标签页之间进行通信
1.通过localStorage
在一个标签页中设置localStorage,在另一个标签页中监听Storage事件。
关于触发Storage事件:
- storage事件,针对都是非当前页面对localStorage进行修改时才会触发,当前页面修改localStorage不会触发监听函数。
- 在对原有的数据的值进行修改时才会触发,比如原本已经有一个key会a值为b的localStorage,你再执行localStorage.setItem(‘a’, ‘b’)代码,是不会触发storag事件的。
标签页1
<input id="name">
<input type="button" id="btn" value="提交">
<script type="text/javascript">
$(function(){
$("#btn").click(function(){
var name=$("#name").val();
localStorage.setItem("name", name);
});
});
</script>
标签页2
<script type="text/javascript">
$(function(){
window.addEventListener("storage", function(event){
console.log(event.key + "=" + event.newValue);
});
});
</script>
2.通过cookie+setInterval
在一个标签页中将要传递的信息存储到cookie中,在另一个标签页中定时读取cookie
标签页1
<input id="name">
<input type="button" id="btn" value="提交">
<script type="text/javascript">
$(function(){
$("#btn").click(function(){
var name=$("#name").val();
document.cookie="name="+name;
});
});
</script>
标签页2
<script type="text/javascript">
$(function(){
function getCookie(key) {
return JSON.parse("{\"" + document.cookie.replace(/;\s+/gim,"\",\"").replace(/=/gim, "\":\"") + "\"}")[key];
}
setInterval(function(){
console.log("name=" + getCookie("name"));
}, 10000);
});
</script>