浏览器:相关知识点

进程与线程

  • 进程是操作系统资源分配的基本单位,进程中包含线程。
  • 线程是由进程所管理的。为了提升浏览器的稳定性和安全性,浏览器采用了多进程模型。

从输入URL到浏览器显示页面发生了什么?

  1. 浏览器查找当前URL是否存在缓存,如果有缓存、并且缓存未过期,直接从缓存中返回
  2. 查看域名是否已经被解析过了,没有解析过进行DNS解析将域名解析成IP地址,并增加端口号
  3. 如果请求是HTTPS,进行SSL协商
  4. 利用IP地址进行寻址
  5. 服务器创建TCP链接 (三次握手)
  6. 服务器响应结果

渲染流程

  1. 需要将HTML转化成DOM树
  2. CSS进行解析,解析成styleSheets
  3. 计算出DOM树中每个节点的具体样式
  4. 创建渲染(布局)树,并计算节点渲染到页面的坐标位置
  5. 通过布局树,进行分层 (根据定位属性、透明属性、transform属性、clip属性等)生产图层树
  6. 将不同图层进行绘制,转交给合成线程处理。最终生产页面,并显示到浏览器上

网络优化策略

  1. 减少HTTP请求数,合并JS、CSS,合理内嵌CSS、JS
  2. 合理设置服务端缓存,提高服务器处理速度。 (强制缓存、对比缓存)
  3. 避免重定向,重定向会降低响应速度 (301,302)
  4. 使用dns-prefetch,进行DNS预解析
  5. 采用域名分片技术,将资源放到不同的域名下。接触同一个域名最多处理6个TCP链接问题。
  6. 采用CDN加速加快访问速度
  7. gzip压缩优化 对传输资源进行体积压缩 (html,js,css)
  8. 加载数据优先级 : preload(预先请求当前页面需要的资源) prefetch(将来页面中使用的资源) 将数据缓存到HTTP缓存中
<link rel="preload" href="style.css" as="style">

关键渲染路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mjiQHWrn-1631675666598)
在这里插入图片描述

减少回流和重绘

静态文件优化

图片优化

图片格式:

  • jpg:适合色彩丰富的照片、banner图;不适合图形文字、图标(纹理边缘有锯齿),不支持透明度
  • png:适合纯色、透明、图标,支持半透明;不适合色彩丰富图片,因为无损存储会导致存储体积大
  • gif:适合动画,可以动的图标;不支持半透明,不适和存储彩色图片
  • webp:适合半透明图片,可以保证图片质量和较小的体积
  • svg格式图片:相比于jpg和jpg它的体积更小,渲染成本过高,适合小且色彩单一的图标;
图片优化:
  • 避免空src的图片
  • 减小图片尺寸,节约用户流量
  • img标签设置alt属性, 提升图片加载失败时的用户体验
  • 原生的loading:lazy 图片懒加载
  • 不同环境下,加载不同尺寸和像素的图片
  • 对于较大的图片可以考虑采用渐进式图片
  • 采用base64URL减少图片请求
  • 采用雪碧图合并图标图片等

HTML优化

  • 语义化HTML:代码简洁清晰,利于搜索引擎,便于团队开发
  • 提前声明字符编码,让浏览器快速确定如何渲染网页内容
  • 减少HTML嵌套关系、减少DOM节点数量
  • 删除多余空格、空行、注释、及无用的属性等
  • HTML减少iframes使用 (iframe会阻塞onload事件可以动态加载iframe)
  • 避免使用table布局

CSS优化

  • 减少伪类选择器、减少样式层数、减少使用通配符
  • 避免使用CSS表达式,CSS表达式会频繁求值, 当滚动页面,或者移动鼠标时都会重新计算 (IE6,7)
background-color: expression( (new Date()).getHours()%2 ? "red" : "yellow" );
  • 删除空行、注释、减少无意义的单位、css进行压缩
  • 使用外链css,可以对CSS进行缓存
  • 添加媒体字段,只加载有效的css文件
<link href="index.css" rel="stylesheet" media="screen and (min-width:1024px)" /> 
  • CSS contain属性,将元素进行隔离
  • 减少@import使用,由于@import采用的是串行加载

JS优化

  • 通过async、defer异步加载文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vWRtHSKm-1631675666602)
在这里插入图片描述

  • 减少DOM操作,缓存访问过的元素
  • 操作不直接应用到DOM上,而应用到虚拟DOM上。最后一次性的应用到DOM上。
  • 使用webworker解决程序阻塞问题
  • IntersectionObserver
const observer = new IntersectionObserver(function(changes) { 
    changes.forEach(function(element, index) {
        if (element.intersectionRatio > 0) {
            observer.unobserve(element.target);
            element.target.src = element.target.dataset.src;
        }
    });
});
function initObserver() {
    const listItems = document.querySelectorAll('img');
    listItems.forEach(function(item) {
        observer.observe(item);
    });
}
initObserver();
  • 虚拟滚动 vertual-scroll-list
  • requestAnimationFrame、requestIdleCallback

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R96wpPZL-1631675666607)
在这里插入图片描述

  • 尽量避免使用eval, 消耗时间久
  • 使用事件委托,减少事件绑定个数。
  • 尽量使用canvas动画、CSS动画

字体优化

@font-face {
    font-family: "Bmy";
    src: url("./HelloQuincy.ttf");
    font-display: block;
    /* block 3s 内不显示, 如果没加载完毕用默认的   */
    /* swap 显示老字体 在替换 */
    /* fallback 缩短不显示时间, 如果没加载完毕用默认的 ,和block类似*/
    /* optional 替换可能用字体 可能不替换*/
}
body {
    font-family: "Bmy"
}

FOUT(Flash Of Unstyled Text) 等待一段时间,如果没加载完成,先显示默认。加载后再进行切换。

FOIT(Flash Of Invisible Text)字体加载完毕后显示,加载超时降级系统字体 (白屏)

优化策略

  • 关键资源个数越多,首次页面加载时间就会越长
  • 关键资源的大小,内容越小,下载时间越短
  • 优化白屏:内联css和内联js,移除文件下载,减小文件体积
  • 预渲染,打包时进行预渲染
  • 使用SSR加速首屏加载(耗费服务端资源),有利于SEO优化。 首屏利用服务端渲染,后续交互采用客户端渲染

浏览器的存储

  • cookie: cookie过期时间内一直有效,存储大小4k左右、同时限制字段个数,不适合大量的数据存储,每次请求会携带cookie,主要可以利用做身份检查。
    • 设置cookie有效期
    • 根据不同子域划分cookie较少传输
    • 静态资源域名和cookie域名采用不同域名,避免静态资源访问时携带cookie
  • localStorage: chrome下最大存储5M, 除非手动清除,否则一直存在。利用localStorage存储静态资源
  • sessionStorage: 会话级别存储,可用于页面间的传值
  • indexDB:浏览器的本地数据库 (基本无上限)

浏览器的事件机制

关键词:事件捕获、事件冒泡、DOM Level 0事件、DOM Level 2事件

事件流

JS 与 HTML 的交互是用事件实现的。事件流描述了页面接收事件的顺序。

事件冒泡

事件冒泡是从最具体的元素开始触发事件,然后向上传播至没有那么具体的元素(或文档)。

事件捕获

事件捕获是从最不具体的节点最先接收事件,向下传播至最具体的节点。事件捕获实际上是为了在事件到达最终目标前拦截事件。

旧版本浏览器不支持事件捕获。

DOM 事件流

DOM2 Events 规范规定事件流分为 3 个阶段: 事件捕获、到达目标 和 事件冒泡。

只有 IE8 以及更早的浏览器不支持

事件处理程序

为了响应用户或者浏览器执行的某种动作( clickloadmouseover … )而调用的 on 开头的函数被称为事件处理程序(事件监听器)。

HTML 事件处理程序

特定的元素支持的每个事件都可以用 HTML 属性的形式使用事件处理程序。其实也就是我们最常使用的方式,如下代码, onclick 属性的值是 JS 代码或者其他的调用方法。

使用事件监听器,浏览器会先创建一个函数来封装属性的值,这个函数有一个特殊的局部变量:event 用来保存 event 对象,事件处理函数中的 this 指向事件的目标元素。。

<input type="button" value="click me" onclick="console.log('click')" />

DOM0 事件处理程序

在 JavaScript 中创建事件监听器的传统方式是把一个函数赋值给 DOM 元素。兼容性最好,所有的浏览器都支持此方法。

每个元素(包括 window 和 document)都有事件处理程序的属性(一般都 onxxxx),这个属性的值为一个函数。

const btn = document.getElementById("myBtn");
btn.onclick = function(){
  console.log('Clicked')
}

DOM0 事件处理是发生在程序赋值时注册在事件流的冒泡阶段的。

所赋值的函数被视为元素的方法,在元素的作用域中运行,this 指向该元素本身。在事件处理程序中通过 this 可以访问元素的任何属性和方法。

将事件处理程序属性设置为 null,即可移除通过 DOM0 方式添加的事件处理程序。

btn.onclick = null;

如果有多个 DOM0 事件处理程序的话,后面的是会把前面的给覆盖掉。只有执行最后一个调用的结果。

DOM2 事件处理程序

我们也可以通过在所有的 DOM 节点上通过 addEventListener()removeEventLinstener() 来添加和移除事件处理程序。

addEventListener()` 和 `removeEventLinstener()` 接收 3 个参数:事件名、事件处理函数 和 一个 option 对象或一个布尔值 `useCapture`( `true` 表示在捕获阶段调用事件处理程序, `false` (默认值)表示在冒泡阶段调用事件处理程序,因为跨浏览器兼容性好,所以事件处理程序默认会被添加到事件流的冒泡阶段(也就是默认最后一个参数为 `false` ))。 `addEventListener(type, listener, useCapture | options)

option 参数有一下几个选择

capture:  Boolean,表示 listener 会在该类型的事件捕获阶段传播到该 EventTarget 时触发。
once:  Boolean,表示 listener 在添加之后最多只调用一次。如果是 true, listener 会在其被调用之后自动移除。
passive: Boolean,设置为true时,表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。

useCapture 参数如下

useCapture  可选
Boolean,在DOM树中,注册了listener的元素, 是否要先于它下面的EventTarget,调用该listener。 当useCapture(设为true) 时,沿着DOM树向上冒泡的事件,不会触发listener。当一个元素嵌套了另一个元素,并且两个元素都对同一事件注册了一个处理函数时,所发生的事件冒泡和事件捕获是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。进一步的解释可以查看 事件流 及 JavaScript Event order 文档。 如果没有指定, useCapture 默认为 false 。
useCapture( option 中的 capture 也是一样)只是控制该事件处理程序是添加在事件流的捕获阶段还是冒泡阶段,对事件的传播是没有影响的!

IE 事件处理程序

IE 实现事件处理程序的方法是: attachEvent()detachEvent() 这两个方法接收两个同样的参数:事件处理程序的名称( eg: onclick )和事件处理函数。因为 IE8 及更早的版本只支持事件冒泡,所以使用 attachEvent() 添加的事件处理程序是添加在冒泡阶段。

const btn = document.getElementById("myBtn");

btn.attachEvent("onclick", function(){
  console.log("Clicked");
})

IE 事件处理程序和 DOM2 事件处理程序有两个不一样的地方

  1. 作用域:attachEvent()是在全局作用域中运行的,所以 attachEvent() 中的函数中的 thiswindow
  2. 执行顺序:IE 事件处理程序的执行顺序是和添加顺序相反的

四种事件处理程序的区别

使用方法移除方法备注
HTML 事件处理程序用 HTML 属性的形式使用事件处理程序 onclick="console.log('click')"同 DOM0 事件处理程序 方式event 局部变量用来保存 event 对象,
this 指向事件的目标元素
DOM0 事件处理程序把一个函数赋值给 DOM 元素 btn.onclick = function(){}btn.onclick = null1. 发生在冒泡阶段
2. this指向元素本身
3. event 局部变量用来保存 event 对象,事件的目标元素
DOM2 事件处理程序addEventListener()removeEventLinstener()1. 接收 3 个参数:事件名、事件处理函数 和 options 或一个布尔值( true 表示在捕获阶段调用事件处理程序,false(默认值)表示在冒泡阶段调用事件处理程序)
2. 可以给一个元素添加多个事件处理程序,并按添加的顺序触发。
3. 使用 addEventListener() 添加的事件处理程序只能使用 removeEventLinstener() 移除(三个参数一致才可以)
4. thisevent同DOM0
IE 事件处理程序attachEvent()detachEvent()1. IE8 及更早的版本只支持事件冒泡
2. attachEvent()是在全局作用域中运行的, thiswindow
3. IE 事件处理程序的执行顺序是和添加顺序相反的
4. event 对象是全局对象 window 的一个属性

Cookie

简介

主要为了辨别用户身份而储存在用户本地终端上的数据

可以记录用户对网站的访问情况(停留时长,访问深度,记录账号密码,在线状态等)

主要由服务端生成然后下发,客户端也可控制其内容

每次发送请求都会自动携带对应域名的cookie

如何使用

服务端

服务端在响应头(Response Header)中添加一个Set-Cookie字段

示例

Set-Cookie:"name=value;expires=session;path=/;domain=.sugarat.top;HttpOnly;secure;sameSite=lax"
客户端(浏览器)
document.cookie

可以通过此 API获取或者修改cookie

Set-Cookie

Set-Cookie 字段的属性介绍

cookie属性简介特殊说明
name-
value-
Expires过期时间一个固定的时间
Max-Age过期时间收到此cookie后多久后过期,优先级大于Expires
Domain可以送达的主机名(域名)-
path生效路径路径必须出现在要请求的资源的路径中才可以发送
Secure安全标志只有使用HTTPS协议的时候才会携带此cookie
HTTPOnly安全标志不允许使用脚本去更改/获取这个cookie
SameSite安全标志控制跨站请求获取cookie

属性补充说明

  • Expires:其值为默认session,即关闭浏览器时此cookie就过期失效
  • Max-Age:不同取值范围不同效果
    • 大于0:会将cookie存到本地文件中
    • 等于0:立即删除
    • 小于0:等价于会话性cookie
    • 优先级大于Expires
  • Domain:指定了 Cookie 可以送达的主机名
    • 没有指定:默认值为当前文档访问地址中的主机部分(不包含子域名)
    • 如果设置为.a.com那么a.com,a.a.comb.a.com等都能访问,即a.com的子域名都可以访问到这个cokie
  • HTTPOnly
    • 防止客户端脚本通过 document.cookie 方式访问或者更改 此Cookie
    • 有助于避免 XSS 攻击
  • SameSite:可以设置让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)
    • Strict:仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,当前网页 URL 与请求目标 URL 完全一致才发送
    • Lax:允许部分(导航到目标网址的 Get 请求)第三方请求携带 Cookie
    • None:无论是否跨站都会发送 Cookie
    • 低版本Chrome中默认值是 None ,在Chrome稳定版80及更高版本上默认是 Lax

SameSite = lax 的影响

Set-Cookie:'name=value;SameSite=Lax;'

大多数情况不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外

  • 超链接
  • GET表单
  • 预加载请求
请求类型示例SameSite = lax 是否发送cooie
超链接
GET表单
预加载
POST 表单
image
iframe
ajaxfetch(url)

Cookie 的作用域

Domain 和 Path 标识共同定义了 Cookie 的作用域:即哪些URL的请求 会携带 目标Cookie

用途

  • 会话状态管理:(如用户登录状态、账号信息等)
  • 个性化设置:(如用户自定义设置、主题等)
  • 用户行为分析:埋点系统(访问深度,停留时长等)

缺点

  • 容量问题:有上限,最大只能有 4KB
  • 性能问题:同一个域名下的所有请求,都会携带 Cookie,某些请求(a,img,link等标签发出的请求)可能不需要此cookie,会加大传输的头部,损耗一定时空开销
  • 安全问题:客户端可以通过一定手段(脚本,devtools,本地存储的文件,修改host文件)获取到,存在XSS,CSRF等安全问题

解决安全问题的方案

  • 减短cookie的有效时间
  • 添加HttpOnly属性:防止本地脚本读取cookie
  • 服务端对传送的cookie加密
  • 添加Secure属性:使用https协议传输
  • 设置samesite属性为需要的值:严格卡控cookie的携带范围

如何删除一个cookie

document.cookie = 'user=jeskson;expires='+new Date(0); // user是cookie的key

localStorage与sessionStorage

浏览器提供的数据存储API,作用相同,生命周期与作用域的不同

window.sessionStorage.setItem()
window.localStorage.setItem()
window.sessionStorage.getItem()
window.localStorage.getItem()

生命周期

  • localStorage 是持久化的本地存储,永远不会过期,除非手动删除
  • sessionStorage 是临时性的本地存储,在会话结束时(关闭页面),存储的内容就被释放

作用域

Local StorageSession StorageCookie 都遵循同源策略

但Session Storage有特殊之处:即便是相同域名下的两个页面,只要它们不在浏览器的同一个Tab中打开,那么它们的 Session Storage 内容便无法共享

优点

  • 存储容量大:不同浏览器,存储容量可以达到 5-10M,针对一个域名
  • 存储于客户端,不会服务端发生通信

缺点

  • 只能存储字符串,JSON对象需要转换为json string 存储
  • 只适用于存储少量简单数据
  • localStorage需要手动删除

应用场景

  • base64图片存储:存储logo
  • 接口数据持久化:对于依赖于接口(变动周期比较长)生成的内容,可以使用storage存储,以加快首屏渲染

IndexedDB

运行在浏览器上的非关系型数据库

依旧受同源策略限制

优点

  • 理论上没有存储上线
  • 可以存储字符串,还可以存储二进制数据
  • 浏览器提供了一套可简单操作的API

应用场景

  • 当数据的复杂度和规模上升到了 LocalStorage 无法解决的程度,就使用IndexDB
  • 临时存储复杂的数据,如页面中的临时文章
  • 一些复杂表单内容的离线保存

使用教程

口诀:

(1)一个语言:不管是WebSQL还是MySQL,SQL的语法必须掌握。SQL是一个结构化查询语言,说白就是用来查询数据的语言中是最自然、最简洁的。

(2)三个函数:分别是:
A. openDatabase 创建或打开一个本地的数据库对象
B. executeSql 执行SQL语句,在回调函数的参数中获取执行结果
C. transaction 处理事务,当一条语句执行失败的时候,之前的执行全部失效

SQL:

(1)概述:

      以下只是把每个功能对应的最基本的SQL语句过一遍。如果不会SQL的,仅做简单语法参考,有兴趣的童鞋需要找资料系统性地全面学习。

(2)创建数据表:

     创建具有多个列,每个列用于存放可不同类型的数据。有列自然有行的概念,行代表一组数据,每组数据是当行对应的多个列的数据集合。

     CREATE TABLE IF NOT EXISTS 表名(列名称1 数据类型,  列名称2 数据类型,  列名称N 数据类型)

(3)查询数据:

     从某表中查询某行某列的数据或查询表中所有元素。

     SELECT 列名称1,列名称2,列名称3 FROM 表名称 WHERE 某列名 = 某值

(4)插入数据:

     向某表中插入行数据,行中每个值对应列名。

     INSERT INTO 表名(列名称1, 列名称2, 列名称N) VALUES (值1, 值2, 值N)

(5)更新数据:

     更新某行中列的值。

     UPDATE 表名 SET 列名称1=新值, 列名称2=新值, 列名称N=新值 WHERE 某列名 = 某值

(6)删除数据:

     删除某行,否则删除所有数据。

     DELETE FROM 表名 WHERE 列名称 = 值

Web SQL本地存储的三个函数:

(1)openDatabase (数据库名字, 数据库版本号, 显示名字, 数据库保存数据的大小, 回调函数(可选))

     不过是否一脸懵逼,好奇怪是不是,参数还要写版本号,还有,显示名字什么鬼?不过,经过测试后,我都是直接这样写就是了(大小请自己定),如下:

      var db = openDatabase("MyDatabase", "", "My Database", 1024*1024);

(2)executeSql(查询字符串, 用以替换查询字符串中问号的参数, 执行成功回调函数(可选), 执行失败回调函数(可选))

     参数一自然是SQL语句,其中值数据可用?代替;参数二是SQL语句中?对应的值(很像PDO的预处理)。注意,executeSql不能单独使用,需要在事务transaction函数下使用。例子如下:

      executeSql("CREATE TABLE IF NOT EXISTS MyData(name TEXT,message TEXT,time INTEGER)");

(3)transaction(包含事务内容的一个方法, 执行成功回调函数(可选), 执行失败回调函数(可选))

     事务内容为一个或多个executeSql函数构成。这个函数很难用语言表达,所以请看例子:

      db.transaction(function(tx){
         tx.executeSql("CREATE TABLE IF NOT EXISTS MyData(name TEXT,message TEXT,time INTEGER)", [], function(){                         alert("create ok")});
             tx.executeSql("SELECT * FROM MyData", [], function(){alert("select ok")});
             tx.executeSql("DROP TABLE IF EXISTS MyData", [], function(){alert("drop ok")});
       });

缓存机制

浏览器第一次向服务器发送请求后拿到结果,会根据响应报文中的HTTP头的缓存标识决定是否缓存结果,是则将结果和缓存标识存入浏览器缓存中。

强制缓存
  1. 不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致)
  2. 存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存
  3. 存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果

当浏览器向服务器发起请求时,服务器会将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Control优先级比Expires高。

Expires:Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间,即再次发起该请求时,如果客户端的时间小于Expires的值时,直接使用缓存结果。到了HTTP/1.1,Expire已经被Cache-Control替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存则会直接失效,这样的话强制缓存的存在则毫无意义。

Cache-Control:在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,主要取值为:

  • public:所有内容都将被缓存(客户端和代理服务器都可缓存)
  • private:所有内容只有客户端可以缓存,Cache-Control的默认取值
  • no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
  • no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
  • max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效

内存缓存(from memory cache)和硬盘缓存(from disk cache)

  • 内存缓存(from memory cache):内存缓存具有两个特点,分别是快速读取和时效性:
  • 快速读取:内存缓存会将编译解析后的文件,直接存入该进程的内存中,占据该进程一定的内存资源,以方便下次运行使用时的快速读取。
  • 时效性:一旦该进程关闭,则该进程的内存则会清空。
  • 硬盘缓存(from disk cache):硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。

浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。

协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:

  1. 协商缓存生效,携带缓存标识发起HTTP请求,资源无更新,返回304,获取该请求的浏览器缓存;
  2. 协商缓存失效,携带缓存标识发起HTTP请求,资源有更新,返回200和请求结果结果,并将结果和缓存标识写入浏览器缓存

协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的,控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag 和 If-None-Match,其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。

Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。

If-Modified-Since则是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。

服务器收到该请求,发现请求头含有If-Modified-Since字段,则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件。

Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。

If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。

服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200。

强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存

HTTP 常用的状态码及使用场景?

  • 1xx:表示目前是协议的中间状态,还需要后续请求
  • 2xx:表示请求成功
  • 3xx:表示重定向状态,需要重新请求
  • 4xx:表示请求报文错误
  • 5xx:服务器端错误

常用状态码:

  • 101 切换请求协议,从 HTTP 切换到 WebSocket
  • 200 请求成功,有响应体
  • 301 永久重定向:会缓存
  • 302 临时重定向:不会缓存
  • 304 协商缓存命中
  • 403 服务器禁止访问
  • 404 资源未找到
  • 400 请求错误
  • 500 服务器端错误
  • 503 服务器繁忙

HTTP 常用的请求方式,区别和用途?

http/1.1 规定如下请求方法:

  • GET:通用获取数据
  • HEAD:获取资源的元信息
  • POST:提交数据
  • PUT:修改数据
  • DELETE:删除数据
  • CONNECT:建立连接隧道,用于代理服务器
  • OPTIONS:列出可对资源实行的请求方法,常用于跨域
  • TRACE:追踪请求-响应的传输路径

计算机网络的认识

应用层、表示层、会话层、传输层、网络层、数据链路层、物理层

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mosowe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值