浏览器缓存策略

参考资料:链接

在浏览器第一次发起请求时,本地无缓存,向web服务器发送请求,服务器起端响应请求,浏览器端缓存。过程如下:
浏览器 - 图1

在第一次请求时,服务器会将页面最后修改时间通过Last-Modified标识由服务器发送给客户端,客户端记录修改时间;服务器还会生成一个Etag,并发送给客户端。
浏览器后续再次进行请求时:
浏览器 - 图2
上图的具体步骤如下:

  • 浏览器请求某一资源时,会先获取该资源缓存的header信息,然后根据header中的Cache-ControlExpires来判断是否过期。若没过期则直接从缓存中获取资源信息,包括缓存的header的信息,所以此次请求不会与服务器进行通信。这里判断是否过期,则是强缓存相关。后面会讲Cache-ControlExpires相关。
  • 如果显示已过期,浏览器会向服务器端发送请求,这个请求会携带第一次请求返回的有关缓存的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事件流就是事件冒泡
浏览器 - 图3
事件捕获 — 由外向内的传播,如以前的远景浏览器
浏览器 - 图4
现在的
chrome浏览器中,执行的是事件冒泡机制。
冒泡阻止** — 阻止事件流向外或向内的传播,stopPropagation()方法

  1. parent1.addEventListener("click", (e) => {
  2. console.log("parent1");
  3. });
  4. parent2.addEventListener("click", (e) => {
  5. console.log("parent2");
  6. });
  7. parent3.addEventListener("click", (e) => {
  8. e.stopPropagation(); // 事件阻止
  9. console.log("parent3");
  10. });

演示如下:
image.png
上面的代码的输出为:parent3。因为stopPropagation()方法在parent3的点击事件中,阻止了向parent2的传播。

  1. 区别于取消事件的默认行为:e.preventDefault(),从英文名就可以判断
  2. IE中阻止冒泡的方法为:e.cancelBubble()方法

事件处理程序

这里的事件指的是用户或者浏览器所执行的事件,对事件进行处理之前需要对事件进行监听,监听到事件发生时,就会执行事件处理程序(一个回调函数)。涉及到的方法如下:
DOM0级 — 作为元素的属性,如btn.onclick,表现形式为

  1. btn.onclick = ()=>{console.log('ok')};

DOM2级事件处理程序addEventListener()removeEventListener()

  1. btn.addEventListener("click",()=>{ // "click"事件是可以绑定多个监听事件的
  2. console.log('ook');
  3. }, false) // 第三个参数是布尔值, true表示捕获阶段, false表示冒泡, 默认false
  4. btn.removeEventListener("click", 第二参数为函数需与需要取消的监听事件是同一事件才能去校) // 所以若是匿名函数,则无法找到了
  5. // 即
  6. btn.addEventListener("click", handler);
  7. btn.removeEventListener("click", handler);

IE事件处理程序attachEvent()detachEvent()

  1. btn.attachEvent("onclick", function(){
  2. alert("Clicked");
  3. });
  4. btn.detachEvent("onclick", 这里的第二参数同理)

跨浏览器的事件处理程序
即将DOM2级和IE事件处理程序封装为一个函数:

301和302

111.png