浏览器缓存策略
参考资料:链接
在浏览器第一次发起请求时,本地无缓存,向web服务器发送请求,服务器起端响应请求,浏览器端缓存。过程如下:
在第一次请求时,服务器会将页面最后修改时间通过Last-Modified
标识由服务器发送给客户端,客户端记录修改时间;服务器还会生成一个Etag,并发送给客户端。
浏览器后续再次进行请求时:
上图的具体步骤如下:
- 浏览器请求某一资源时,会先获取该资源缓存的header信息,然后根据header中的
Cache-Control
和Expires
来判断是否过期。若没过期则直接从缓存中获取资源信息,包括缓存的header的信息,所以此次请求不会与服务器进行通信。这里判断是否过期,则是强缓存相关。后面会讲Cache-Control
和Expires
相关。 - 如果显示已过期,浏览器会向服务器端发送请求,这个请求会携带第一次请求返回的有关缓存的header字段信息,比如客户端会通过
If-None-Match
头将先前服务器端发送过来的Etag发送给服务器,服务会对比这个客户端发过来的Etag是否与服务器的相同,若相同,就将If-None-Match
的值设为false,返回状态304,客户端继续使用本地缓存,不解析服务器端发回来的数据,若不相同就将If-None-Match
的值设为true,返回状态为200,客户端重新机械服务器端返回的数据;客户端还会通过If-Modified-Since
头将先前服务器端发过来的最后修改时间戳发送给服务器,服务器端通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回最新的内容,如果是最新的,则返回304,客户端继续使用本地缓存。
浏览器与JS运行机制梳理
参考资料:浏览器多进程到JS单线程
请求头/响应头
http请求头: Request Headers
Accept: /
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 1023
Content-Type: application/json; charset=UTF-8
cache-control: max-age=0
Cookie: ab={}; auth=eyJ0b2tlbiI6ImV5SmhZMk5sYzNOZmRHOXJaVzRpT2lKaWQybEZRVFpFYUVsaldsRkVPV1pWSWl3aWNtVm1jbVZ6YUY5MGIydGxiaUk2SWxoUmRHUXhPRFpuV1VOa2JYQTRTV2dpTENKMGIydGxibDkwZVhCbElqb2liV0ZqSWl3aVpYaHdhWEpsWDJsdUlqb3lOVGt5TURBd2ZRPT0iLCJjbGllbnRJZCI6MTU4OTE2MTQyMTI3NSwidXNlcklkIjoiNWU4ZjYxY2M2ZmI5YTAzYzMwMGY5MjAxIn0=; auth.sig=KqdA8JkH61GsxKIxiER7v54gZ8U; QINGCLOUDELB=229d9a3634d498216e02f8b4f3770be609f51ba16147f64a21f5d51a89fcd206|XsODW|XsODV
DNT: 1
if-none-match: W/“1ij0d”
if-modified-since: Mon, 04 May 2020 14:06:31 GMT
Host: juejin.im
Origin: https://juejin.im
Referer: https://juejin.im/post/5ce120fbe51d4510a50334fa
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
响应头:Response Headers
ccess-control-allow-headers:
access-control-allow-methods: GET, OPTIONS, HEAD, PUT, POST
access-control-allow-origin: https://juejin.im
access-control-max-age: 1800
Access-Control-Max-Age: 86400
cache-control: no-store, no-cache, must-revalidate
Connection: close
Content-Encoding: gzip
content-length: 9096
Content-Type: application/json; charset=utf-8
Date: Tue, 19 May 2020 06:57:25 GMT
eagleid: 6fce044615898714458473498e
etag: W/“1ij0d”
expires: 0
pragma: no-cache
Server: nginx
server-timing: inner; dur=0, cdn-cache;desc=MISS,edge;dur=0,origin;dur=18
Strict-Transport-Security: max-age=31536000
timing-allow-origin:
*status: 304
Transfer-Encoding: chunked
via: cache14.cn779-1[18,0]
X-Frame-Options: SAMEORIGIN
x-tt-trace-host: 01a417ed956abfb8a0fa7a232fa7c41b8d916cb4113bd207a84b0fdea634fecf55eacda6ae363ab18ca77b3c5d206702f3b79a2189a6dbc88c60c6be43a8a6af8a9435112bd976cecee609accfc75fcf193bb0caa335fb7b00227c234d4cb52c20a34b8cd6f47003cbb88cfb02e209d0d6
x-tt-trace-tag: id=3;cdn-cache=miss
浏览器事件
浏览器事件分为事件冒泡和事件捕获。
事件冒泡** — 由内到外的传播,典型的如IE事件流就是事件冒泡
事件捕获 — 由外向内的传播,如以前的远景浏览器
现在的chrome浏览器中,执行的是事件冒泡机制。
冒泡阻止** — 阻止事件流向外或向内的传播,stopPropagation()
方法
parent1.addEventListener("click", (e) => {
console.log("parent1");
});
parent2.addEventListener("click", (e) => {
console.log("parent2");
});
parent3.addEventListener("click", (e) => {
e.stopPropagation(); // 事件阻止
console.log("parent3");
});
演示如下:
上面的代码的输出为:parent3。因为stopPropagation()
方法在parent3的点击事件中,阻止了向parent2的传播。
- 区别于取消事件的默认行为:
e.preventDefault()
,从英文名就可以判断- IE中阻止冒泡的方法为:
e.cancelBubble()
方法
事件处理程序
这里的事件指的是用户或者浏览器所执行的事件,对事件进行处理之前需要对事件进行监听,监听到事件发生时,就会执行事件处理程序(一个回调函数)。涉及到的方法如下:
DOM0级 — 作为元素的属性,如btn.onclick,表现形式为
btn.onclick = ()=>{console.log('ok')};
DOM2级事件处理程序:addEventListener()
和removeEventListener()
btn.addEventListener("click",()=>{ // "click"事件是可以绑定多个监听事件的
console.log('ook');
}, false) // 第三个参数是布尔值, true表示捕获阶段, false表示冒泡, 默认false
btn.removeEventListener("click", 第二参数为函数需与需要取消的监听事件是同一事件才能去校) // 所以若是匿名函数,则无法找到了
// 即
btn.addEventListener("click", handler);
btn.removeEventListener("click", handler);
IE事件处理程序:attachEvent()
和 detachEvent()
btn.attachEvent("onclick", function(){
alert("Clicked");
});
btn.detachEvent("onclick", 这里的第二参数同理)
跨浏览器的事件处理程序
即将DOM2级和IE事件处理程序封装为一个函数: