前端一些心得笔记

HTML基础

1.HTML文件中的DOCTYPE是什么作用?

HTML超文本标记语言:是一个标记语言,就有对应的语法标准

DOCTYPE即Document Type,网页文件的文档类型标准。

主要作用是告诉浏览器的解析器要使用哪种HTML规范或XHTML规范来解析页面。

DOCTYPE需要放置在HTML文件的标签之前

2.HTML、XML、XHTML之间有什么区别

他们都属于标记语言

语言 中文名 说明
HTML4 超文本标记语言 主要用于做截面呈现。HTML是先有实现,后面才慢慢制定标准的,导致HTML非常混乱,语法非常的不严谨
XML 可扩展标记语言 主要用于存储数据和结构。语法严谨,可扩展性强。由于JSON也有类似作用但更轻量高效,XML的市场变得越来越小。
XHTML 可扩展超文本标记语言 属于加强版的HTML,为解决HTML的混乱问题而生,在语法方面变得和XML一样严格。另外,XHTML的出现也催生了HTML5,让HTML向规范化严谨化过渡。
HTML5 超文本标记语言 在HTML的基础上进行拓展,用于页面呈现(目前标准)

XML的要求会比较严格:

1.有且只能有一个根元素

2.大小写敏感

3.正确嵌套

4.必须双引号

5.必须闭合标签

3.前缀为data- 开头的元素属性是什么?

这是一种为HTML元素添加额外数据信息的方式,被称为自定义属性。

4.对HTML语义话的一个理解

语义化的好处(利于SEO、可阅读性好)

5.HTML5对比HTML4有哪些不同之处?

1.只有一种DOCTYPE文件类型声明(统一标准)

2.增加了一些新的标签元素(功能,语义化)

常用功能:vedio、canvas

常用语义化:section、footer、header、nav…

3.input支持了几个新的类型值,如:date、email、url等

4.新增了一些标签属性,如:charset、async

5.新增的全域属性,如:contenteditable、draggable、hidden…

6.新增API,如:本地存储,地理定位,canvas绘图,拖拽API,即时通信…

6.meta标签哪些常用用法?

mate标签的具体功能一般由name/http-equiv和content两部分属性来定义。

  • 如果设置name属性,则它描述的是网页文档的信息(例如:作者、日期和时间、网页描述、关键词)
  • 如果设置http-equiv属性,则它描述的相当于是HTTP响应头信息(例如:网页内容信息、网页缓存等)

一些常用的功能:

1.设置网页关键词(SEO)

2.设置网页视口(viewport)控制视口的大小、缩放和比例等

3.设置http响应头:Content-Type网页内容类型(字符集)

7.img标签的srcset的作用是什么?

处理响应式图片的方式(css媒体查询换的是背景图片,而不是img标签的src)

开发者和设计师们竞相寻求处理响应式图片的方法。这的确是一个棘手的问题,因为我们对同一个网站在众多设备宽度下,使用同一个网站在众多设备宽度下,使用同一图像源。

其实通过使用img标签的srcset属性,可定义一组额外的图片集合,让浏览器根据不同的屏幕状况选取合适的图片来显示。

如果你的响应式需求比较简单,只需要针对屏幕的不同dpr(device pixel ratio,设备像素倍率)来决定图片的显示的话,那么就只要这么写:

对于可变宽度的图像,我们使用srcset搭配w描述符以及sizes属性。

  • w描述符告诉浏览器列表中的每个图像的宽度
  • sizes属性需要至少包含两个值,是由逗号分隔的列表

根据最新规范,如果srcset中任何图像使用了w描述符,那么必须要设置sizes属性。

sizes属性有两个值:

1.第一个是媒体查询条件

2.第二个是图片对应的尺寸值,

在特定媒体条件下,此值决定了图片的宽度。

需要注意是,源图尺寸值不能使用百分比,如果要用100%,vw是唯一可用的CSS单位。

注意:测试时,清除缓存测试,因为一旦加载了高清图,就不会也没必要,回过去再用小图替换了。且我们无法确定究竟显示哪张图像,因为每个浏览器根据我们提供的信息挑选适当图像的算法是有差异的。

8.响应式图片处理优化:Picture标签

picture元素就像是图像和其源的容器。浏览器仍然需要img元素,用来表明需要加载的图片在picture下放置零个或多个source标签,以及一个img标签,为不同的屏幕设备和场景显示不同的图片。如果source匹配到了,就会优先用匹配到的,如果没有匹配到会往下继续找。

使用picture元素选择图像,不会有歧义。

浏览器的工作流程如下:

  • 浏览器会先根据当前情况,去匹配和使用source提供的图片
  • 如果未匹配到合适的source,就使用img标签提供的图片

9.在script标签上使用defer和async的区别是什么?

script标签存在两个属性,defer和async,因此script标签的使用分为三种情况:

1.< script src = “example.js”>< /script>

没有defer或async属性,浏览器会立即加载并执行相应脚本。

不等待后续加载的文档元素,读到就开始加载和执行,此举会阻塞后续文档的加载

2.< script async src = “exaple.js”>< /script>

有了async属性,表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行

3.< script defer src = “exaple.js”>< /script>

有了defer属性,加载后续文档的过程和js脚本的加载是并行进行的(异步),此时的js脚本不仅加载不执行,js脚本的执行需要等待文档所有元素解析完成后,DOMContentLoaded事件触发执行之前。

async和defer的特点

1.defer和async在网络加载过程是一致的,都是异步执行的

2.两者的区别,脚本加载完成之后,async是立刻执行,defer会等一等

所以,js脚本加上async或defer,放在头部可以减少网页的下载加载时间,如果不考虑兼容性,可以用于优化页面加载的性能。

async使用场景:适合于不依赖于其他js文件的脚本加载

10.前端web存储的方式

1.localStorage (存储大小5M)

2.sessionStorage (存储大小5M,关闭浏览器就会自动销毁数据)

3.cookies(存储大小4k)(可以设置过期时间,缺点存储容量太小,操作不方便)

4.web SQl (用的少,sql语句,会影响网页性能)

5.IndexDB (适合存储大量的数据 大小>=250M,甚至没上限。异步操作,性能好)

CSS基础

1.CSS选择器的优先级是什么样的?

CSS选择器的优先级顺序:

!important>内嵌样式>ID选择器>类选择器>标签选择器>通配符>继承

优先级计算

优先级是由A、B、C、D四个值来决定的,具体计算规则如下

  • A={如果存在内联样式则为1,否则为0}
  • B={ID选择器出现的次数}
  • C={类选择器、属性选择器、伪类选择器出现的总次数}
  • D={标签选择器、伪元素选择器出现的总次数}

2.通过CSS的哪些方式可以实现隐藏页面上的元素?

方式 说明
opacity:0 通过将元素的透明度设置为0,实现看起来隐藏的效果,但是依旧会占用空间并可以进行交互效果
visibility:hidden 与透明度为0的方案非常类似,会占据空间,但不可以进行交互
overflow:hidden 只会隐藏溢出的部分,占据空间并不可交互
display:none 可以彻底隐藏元素并从文档流中消失,不占据空间也不能交互,且不影响布局
z-index:-999 通过将元素的层级置于最底层,让其他元素覆盖住它,达到看起来隐藏的效果
transform:scale(0,0) 通过将元素进行缩放,缩放为0;依然会占据空间,但不可交互
left:-9999999px 通过将元素定位到屏幕外,达到看起来看不到的效果

3.px,em,rem之间的区别?

px:绝对单位

em:相对单位,相对于父盒子的font-size

rem:相对单位,相对于html根标签

=>rem 一般可以用于rem适配

适配原理是什么?

1.使用rem作为单位

2.动态的设置不同屏幕下的html的font-size(媒体查询,js(插件flexible.js))

4.让元素水平居中的方法有哪些?

方法一:使用margin

通过元素设置左右的margin为auto,实现让元素居中

方法二:使用定位

父盒子相对位移,子盒子绝对位移去实现居中

方法三:text-align:center

子盒子转成行内块元素,父盒子添加text-align:center

方法四:flex盒子

父盒子的justify-content和align-items设置center

5.在CSS中哪些定位方式?

position:

1.static(默认)

2.fixed 固定定位

3.absolute 绝对定位

4.relative 相对定位

5.sticky 粘性定位(吸顶效果)

6.如何理解z-index?

可以将它看做三维坐标中的z轴方向上的图层层叠顺序

元素默认的z-index为0,可通过修改z-index来控制设置了position值的元素的图层位置。

如果父辈元素有定位,且配置了z-index,优先按照父辈元素定位的z-index进行层级比较。

7.如何清除浮动?

1.定高法

给浮动元素定一个指定高度

2.添加一个子盒子,clear:both;

3.overflow:hidden;

4.利用伪元素 clearfix

8.BFC的理解

BFC:块级格式化上下文,是一块独立的渲染区域。将处于BFC区域内和区域外的元素进行相互隔离。

触发BFC的方式:

1.position:absolute/fixed

2.float:left/right

3.overflow:非visible hidden/auto/scroll

4.display:inline-block

BFC运用:

1.处理块级元素,上下margin合并的问题

2.处理margin塌陷

3.清除浮动

4.实现自适应布局

9.什么是CSS Sprites以及它的好处?

CSS Sprites,俗称雪碧图,精灵图。这是一种CSS图片合并技术,就是将CSS中原先引用的一些较小的图片,合成一张稍大的图片后再引用的技术方案。它可以减少请求多张小图片带来的网络消耗(因为发起的HTTP请求次数变少了),并实现提前加载资源的效果。

缺点:

  • CSS Sprites中的任意一个小图标改动,都需要重新生成大图;并且用户端需要重新下载整张大图,这就降低了浏览器缓存的优势。
  • 随着HTTP2的逐渐普及,HTTP2的多路复用机制可以解决请求多个小图片所创建多个HTTP请求的消耗,让CSS Sprites存在的价值降低了
  • 图片放大就容易失真

目前其他主流的处理图片的方案:iconfont字体图标,svg矢量图标

10.你对媒体查询的理解是什么样的?

@media screen and (min-width :992px)and(max-width:x1200px){

.box{

width:980px

}

}

11.你对盒子的理解是什么?标准盒子模型和怪异盒子模型的区别是什么?

盒子大小的组成:

  • 内容(content)
  • 内边距(padding)
  • 边框(border)
  • 外边距(margin)

标准盒子模型和怪异盒子模型的区别主要在元素尺寸的表示上。

盒模型的指定:

在CSS3中,我们可以通过设置box-sizing的值来决定具体使用何种盒模型

  • content-box 标准盒模型
  • border-box 怪异盒模型

标准盒模型:

box-sizing:content-box(默认值)

12.伪类和伪元素的区别

什么是伪类?

伪类是以冒号:为前缀,可被添加到一个选择器的末尾的关键字。

它用于样式在元素的特定状态下应用到元素上。比如:checked、:hover、:disabled、:first child等。

注意:伪类,虽然是写法比较特殊,css选择器的权重,和类一致的。

什么是伪元素?

伪元素用于创建一些不在DOM树中的元素,并为其添加样式。伪元素的语法和伪类类似,可以一个冒号或两个冒号为前缀。

比如,可以通过:before、:after来在一个元素前、后增加一些额外的文本并为他们添加样式

并且,虽然用户可以看到这些文本,但其实他们并不在DOM树中。(伪元素是无法注册事件的,所以不要通过js控制伪元素。)

两者的区别

虽然他们在语法上是一致的,但是他们的功能区别还是非常明显的

  • 伪类是用来匹配元素的特殊状态的
  • 伪元素是用来匹配元素的隶属元素的,这些隶属元素可以在界面中展示,但在DOM中不体现

13.flex的理解

flex语法小结:

display:flex 设置flex盒子

flex-direction:调整主轴方向 row:主轴方向为水平向右 column:主轴方向为竖直向下

justfy-content:主要用来设置主轴方向的对齐方式 center space-around space-between flex-start flex-end

align-items:主要用来设置侧轴方向的对齐方式 stretch(拉伸,不设高度,会拉伸拉满100%) flex-start flex-end center

flex-wrap:wrap 换行

align-content 用来设置多行的flex容器的排列方式 center space-around space-between flex-start flex-end stretch

JS基础

1.什么是变量提升?

变量提升是负责解析执行代码的JavaScript引擎的工作方式产生的一个特性。

JS引擎在运行一份代码的时候,会按照下面的步骤进行工作:

1.首先,对代码进行预解析,并获取声明的所有变量

2.然后,将这些变量的声明语句统一放到代码的最前面

3.最后,开始一行一行运行代码

2.JS参数是以什么方式进行传递的?

基本数据类型和复杂数据类型在传递时,会有不同的表现

简单类型,进行参数传递,传递的是值本身

复杂类型,进行参数传递时,传递的是地址

3.JS垃圾回收是怎么做的?

JS中内存的分配和回收都是自动完成的,内存在不使用会被垃圾回收器自动回收。

正因为垃圾回收器的存在,许多人认为JS不用太关心内存管理的问题。

但如果不了解JS内存管理机制,我们同样非常容易内存泄漏(内存无法被回收)的情况。

3.1内存的生命周期

JS环境中分配的内存,一般有如下生命周期:

1.内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存

2.内存使用:即读写内存,也就是使用变量、函数等

3.内存回收:使用完毕,由垃圾自动回收不再使用的内存

全局变量一般不会回收,一般局部变量的值,不用了,会被自动回收

3.2垃圾回收算法说明

所谓垃圾回收,核心思想就是如何判定内存是否已经不再使用了,如果是,就视为垃圾,释放掉

3.3引用计数

IE采用的引用计数算法,定义“内存不再使用”的标准很简单,就是看一个对象是否有指向它的引用。如果没有其他条件指向它了,说明该对象已经不再需要了。

它有一个致命的问题:循环引用。

如果两个对象相互引用,尽管他们已不再使用了,垃圾回收器不会进行回收,导致内存泄漏。

3.4标记清除法

现代的浏览器已经不再使用引用计数法了。

现代浏览器通用的大多是基于标记清除算法的某些改进算法,总体思想都是一致的。

标记清除法:

  • 标记清除算法将“不再使用对象”定义为“无法达到的对象”
  • 简单来说,就是从根部(在JS中就是全局对象)出发定时扫描内部的对象
  • 凡是能从根部到达的对象,都是还需要使用的。那些无法由根部出发触及到的对象被标记为不再使用。稍后进行回收。

从这个概念可以看出,无法触及的对象包括了没有引用的对象这个概念(没有任何引用的对象也是无法触及的对象)

4.JS作用域链的理解

JS在执行过程中会创建一个个的可执行上下文。(每个函数都会创建这么一个可执行上下文)

每个可执行上下文的词法环境中包含了对外部词法环境的引用,可通过该引用来获取外部词法环境中的变量和声明等。这些引用串联起来,一直指向全局的词法环境,形成一个链式结构,被称为作用域链。

简而言之:函数内部可以访问到函数外部作用域变量,而函数外部还可以访问到全局作用域的变量,这样变量的作用域访问的链式结构,被称之为作用域链

5.对闭包的理解

什么是闭包?

闭包是函数和声明该函数的词法环境的组合

更通俗一点的解释是:

内层函数,引用外层函数上的变量,就可以形成闭包(常用于实现数据私有)

注意:外部函数中,一般需要return引用内部函数(这样内存才不会被释放掉)

会导致内存泄漏,所以结尾要把函数=null,断开了内部函数的引用,对应缓存的变量内容也会被释放掉

6.JS中数据类型的隐式转换规则

在if语句、逻辑语句、数学运算逻辑、==等情况下都可能出现隐式类型转换。

原始值 转化数值类型 转化为字符串类型 转化为Boolean类型
false 0 ‘false’ false
true 1 ‘true’ true
0 0 ‘0’ false
1 1 ‘1’ true
‘0’ 0 ‘0’ true
‘1’ 1 ‘1’ true
NaN NaN ‘NaN’ false
Infinlty Infinlty ‘Infinlty’ true
-Infinlty -Infinlty ‘-Infinlty’ true
‘’ 0 ‘’ false
‘20’ 20 ‘20’ true
‘twenty’ NaN ‘twenty’ true
[] 0 “” true
[20] 20 ‘20’ true
[10,20] NaN ‘10,20’ true
[‘twenty’] NaN ‘twenty’ true
[‘ten’,‘twenty’] NaN ‘ten,twenty’ true
function(){} NaN ‘function(){}’ true
{} NaN ‘[object,Object]’ true
null 0 ‘null’ false
undefined NaN ‘undefined’ false

注意:判断时尽量不要用‘’,要用‘=’(==判断,如果类型不同,默认会进行隐式转化再比较)

7.对原型链的理解

  • 什么是原型对象
  • 构造函数,原型对象,实例对象
  • 原型链如何形成的

原型对象

在JS中,除去一部分内建函数,绝大多数的函数都会包含一个叫做prototype的属性,指向原型对象,基于构造函数创建出来的实例,都可以共享访问原型对象的属性。

例如我们的hasOwnProperty,toString方法等其实是Object原型对象的方法,它可以被任何对象当做自己的方法来使用。

8.对于继承的理解

为什么要学习继承?

写的构造函数,定义了一个类型(人类),万一项目非常大,又有了细化的多个类型(老师,工人,学生)

学习了继承,可以让多个构造函数之间建立关联,便于管理和复用

什么是继承?

继承:从别人那里,继承东西过来

代码层面的继承:继承一些属性和方法

8.1 继承-原型继承

分析需求:

人类,属性:name,age

学生,属性:name,age,className

工人,属性:name,age,companyName

无论学生,还是工人,=>都是人类,所以人类原型上有的方法,他们都应该要有

为什么要有继承:

将多个构造函数,建立关联,实现方便管理和方便复用

原型继承:通过改造原型链实现的继承,利用原型链的特征实现继承。(继承方法)

8.2继承-组合继承

组合继承有时候也叫做伪经典继承,指的是将原型链和借用构造函数call技术组合到一块,

从而发挥二者之长的一种继承模式,其背后的思路:是使用原型链实现对原型属性和方法的继承(主要是方法)

而通过借用构造函数来实现对实例属性的继承。这样既通过在原型上定义方法实现了函数复用,又能保证每个实例都有它自己的属性。

8.3寄生组合继承

实例上有参数,而原型__ proto __ 上不需要再有这些属性,所以利用Object.create改装下Object.create(参数对象),Object.create会创建一个新对象,而且这个新对象 __ proto __会指向传入参数对象

8.4es6-class实现继承extends

例子:

class Person {

constructor(name, age) {

​ this.name = name

​ this.age = age

}

run() {

​ console.log(‘我会跑’);

}

}

class Student extends Person {

constructor(name, age, className) {

​ super(name, age)

​ this.className = className

}

study() {

​ console.log(‘我会学习’);

}

}

const Stu = new Student(‘zs’, 23, 1812321)

console.log(Stu);

9.如何判断是否是数组?

Object.prototype.toString方法,可以很方便的判断类型

判断数组的话,用Object.prototype.toString.call(要判断的元素)或者Array.isArray(要判断的元素)

10.this的理解

this指向情况:

1.函数调用模式 fn() 指向window (默认绑定)

2.方法调用模式 obj.fn() 指向调用者 指向obj(隐式绑定)

3.上下文调用模式 call apply bind 想指向谁就指向谁(显示绑定,硬绑定)

call和apply、bind区别

call是一个个传递 fn.call(this指向内容,参数1,参数2,参数3…)

apply是数组形式传递 fn.apply(this指向内容,[参数1,参数2,参数3…])

bind:const fn = fn.bind(this指向的内容)

4.构造函数模式 new Person() 指向创建实例 (new绑定)

11.箭头函数中的this指向什么

箭头函数不同于传统函数,它其实没有属于自己的this,

它所谓的this是捕获其外层上下文的this值作为自己的this值。

并且由于箭头函数没有属于自己的this,它是不能被new调用的。

12.Promise的静态方法

promise的三个状态:pending(默认) fullfilled(成功) rejected(失败)

1.resolve函数被执行时,会将promise的状态从pending改成fullfilled成功

2.reject函数被执行时,会将promise的状态从pending改成rejected失败

Promise.reject()

Promise.resolve()

Promise.all([promise1,promise2,promise3])等待原则,是在所有promise都完成后执行,可以用于处理一些并发的任务

Promise.race([promise1,promise2,promise3])赛跑,只要三个promise有一个满足条件,就会执行.then(用的比较少)

13.宏任务与微任务是什么

宏任务:主线程代码,setTimeout等属于宏任务,上一个宏任务执行完成,才会考虑下一个宏任务。

微任务:promise.then.catch的内容,属于微任务,满足条件的微任务,会被添加到当前宏任务的最后去执行(上一个宏任务完成后,下一个宏任务开始前执行)

js执行主线程,代码一行一行往下执行,js是单线程的

js执行时,只要遇到了异步的函数,不会停留,会将异步函数交给浏览器

浏览器是多线程,可以同时处理多个事件(等待,监听)

只有主线程空闲了,才会考虑任务队列的代码

满足条件,将需要执行的内容,在任务队列中排队

执行顺序

1.先执行所有同步任务,碰到异步任务放到任务队列中

2.同步任务执行完毕,开始执行当前所有的异步任务

3.先执行任务队列里面所有的微任务

4.然后执行一个宏任务

5.然后再执行所有的微任务

6.再执行一个宏任务,再执行所有的微任务·······依次类推到执行结束。

14.async/await是什么?

ES7 标准中新增的 async 函数,从目前的内部实现来说其实就是 Generator 函数的语法糖。

它基于 Promise,并与所有现存的基于Promise 的 API 兼容。

async 关键字

  1. async 关键字用于声明⼀个异步函数(如 async function asyncTask1() {...}

  2. async 会⾃动将常规函数转换成 Promise,返回值也是⼀个 Promise 对象

  3. async 函数内部可以使⽤ await

await 关键字

  1. await 用于等待异步的功能执⾏完毕 var result = await someAsyncCall()
  2. await 放置在 Promise 调⽤之前,会强制async函数中其他代码等待,直到 Promise 完成并返回结果
  3. await 只能与 Promise ⼀起使⽤
  4. await 只能在 async 函数内部使⽤

15.相较于 Promise,async/await有何优势?

  1. 同步化代码的阅读体验(Promise 虽然摆脱了回调地狱,但 then 链式调⽤的阅读负担还是存在的)
  2. 和同步代码更一致的错误处理方式( async/await 可以⽤成熟的 try/catch 做处理,比 Promise 的错误捕获更简洁直观)
  3. 调试时的阅读性, 也相对更友好

16. 深拷贝 浅拷贝

引用类型, 进行赋值时, 赋值的是地址

  1. 浅拷贝

    let obj = {
    	name: 'zs',
    	age: 18
    }
    let obj2 = {
        ...obj
    }
    
  2. 深拷贝

    let obj = {
    	name: 'zs',
    	age: 18,
        car: {
            brand: '宝马',
            price: 100
        }
    }
    
    let obj2 = JSON.parse(JSON.stringify(obj))
    console.log(obj2)
    

    当然递归也能解决, 只是比较麻烦~

其他方案, 可以参考一些博客

HTTP协议

1. HTTP有哪些⽅法?

HTTP 1.0 标准中,定义了3种请求⽅法:GET、POST、HEAD

HTTP 1.1 标准中,新增了请求⽅法:PUT、PATCH、DELETE、OPTIONS、TRACE、CONNECT

2. 各个HTTP方法的具体作用是什么?

方法 功能
GET 通常⽤于请求服务器发送某些资源
POST 发送数据给服务器
HEAD 请求资源的头部信息, 并且这些头部与 HTTP GET ⽅法请求时返回的⼀致。
该请求⽅法的⼀个使⽤场景是在下载⼀个⼤⽂件前先获取其⼤⼩再决定是否要下载, 以此可以节约带宽资源
PUT ⽤于全量修改⽬标资源 (看接口, 也可以用于添加)
DELETE ⽤于删除指定的资源
OPTIONS ⽤于获取⽬的资源所⽀持的通信选项 (跨域请求前, 预检请求, 判断目标是否安全)
TRACE 该方法会 让服务器 原样返回任意客户端请求的信息内容, 用于诊断和判断
CONNECT HTTP/1.1协议中预留给能够将连接改为管道⽅式的代理服务器
(把服务器作为跳板,让服务器代替用户去访问其它网页, 之后把数据原原本本的返回给用户)
PATCH ⽤于对资源进⾏部分修改

3. GET方法和POST方法有何区别?

默认的http请求的内容, 在网络中传输, 明文的形式传递的 (https 对内容加密)

GET方法 POST方法
数据传输⽅式 通过URL传输数据 (地址栏拼接参数) 通过请求体传输
数据安全 数据暴露在URL中,可通过浏览历史记录、缓存等很容易查到数据信息 数据因为在请求主体内,
所以有⼀定的安全性保证
数据类型 只允许 ASCII 字符 ⽆限制
GET⽆害 刷新、后退等浏览器操作是⽆害的 可能会引起重复提交表单
功能特性 安全且幂等(这⾥的安全是指只读特性,就是使⽤这个⽅法不会引起服务器状态变化。
幂等的概念是指同⼀个请求⽅法执⾏多次和仅执⾏⼀次的效果完全相同)
⾮安全(会引起服务器端的变化)、⾮幂等

4. HTTP请求报文是什么样的?

HTTP 请求报⽂的组成:请求⾏、请求头、(空⾏)、请求体。

请求行

包含了请求⽅法、URL、HTTP 协议版本,它们之间⽤空格进行分隔。例如:

GET http://www.abc.com/articles HTTP/1.1

请求头

请求头由键值对组成,每⾏⼀对,键值之间⽤英⽂冒号:进行分隔。例如:

Content-Type: application/json
Host: www.abc.com

请求体

请求体中放置 POST、PUT、PATCH 等请求方法所需要携带的数据。

5. HTTP响应报文是什么样的?

HTTP 响应报⽂的组成: 响应⾏、响应头、空⾏、响应体。

响应行

响应行由协议版本、状态码、状态码的原因短语3个内容组成,中间以空格分隔。例如:

HTTP/1.1 200 OK

响应头

响应头由键值对组成,每⾏⼀对,键值之间⽤英⽂冒号:进行分隔。例如:

Content-Length: 1024
Content-Type: application/json

响应体

服务器发送过来的数据。

6. 你了解的HTTP状态码有哪些?

成功(2XX)

状态码 原因短语 说明
200 OK 表示从客户端发来的请求在服务器端被正确处理
201 Created 请求已经被实现,⽽且有⼀个新的资源已经依据请求的需要⽽建⽴
通常是在POST请求,或是某些PUT请求之后创建了内容, 进行的返回的响应
202 Accepted 请求服务器已接受,但是尚未处理,不保证完成请求
适合异步任务或者说需要处理时间比较长的请求,避免HTTP连接一直占用
204 No content 表示请求成功,但响应报⽂不含实体的主体部分
206 Partial Content 进⾏的是范围请求, 表示服务器已经成功处理了部分 GET 请求
响应头中会包含获取的内容范围 (常用于分段下载)

重定向(3XX)

状态码 原因短语 说明
301 Moved Permanently 永久性重定向,表示资源已被分配了新的 URL
比如,我们访问 http/www.baidu.com 会跳转到 https/www.baidu.com
302 Found 临时性重定向,表示资源临时被分配了新的 URL, 支持搜索引擎优化
首页, 个人中心, 遇到了需要登录才能操作的内容, 重定向 到 登录页
303 See Other 对于POST请求,它表示请求已经被处理,客户端可以接着使用GET方法去请求Location里的URI。
304 Not Modified 自从上次请求后,请求的网页内容未修改过。
服务器返回此响应时,不会返回网页内容。(协商缓存)
307 Temporary Redirect 对于POST请求,表示请求还没有被处理,客户端应该向Location里的URI重新发起POST请求。
不对请求做额外处理, 正常发送请求, 请求location中的url地址

因为post请求, 是非幂等的, 从302中, 细化出了 303 和 307

简而言之:

  • 301 302 307 都是重定向
  • 304 协商缓存

客户端错误(4XX)

状态码 原因短语 说明
400 Bad Request 请求报⽂存在语法错误((传参格式不正确)
401 UnAuthorized 权限认证未通过(没有权限)
403 Forbidden 表示对请求资源的访问被服务器拒绝
404 Not Found 表示在服务器上没有找到请求的资源
408 Request Timeout 客户端请求超时
409 Confict 请求的资源可能引起冲突

服务端错误(5XX)

状态码 原因短语 说明
500 Internal Sever Error 表示服务器端在执⾏请求时发⽣了错误
501 Not Implemented 请求超出服务器能⼒范围,例如服务器不⽀持当前请求所需要的某个功能,
或者请求是服务器不⽀持的某个⽅法
503 Service Unavailable 表明服务器暂时处于超负载或正在停机维护,⽆法处理请求
505 Http Version Not Supported 服务器不⽀持,或者拒绝⽀持在请求中使⽤的 HTTP 版本

7. HTTP的keep-alive是什么作用?

作用:使客户端到服务器端的连接持续有效(长连接),当出现对服务器的后继请求时,

Keep-Alive功能避免了建立或者重新建立连接。

早期 HTTP/1.0 在每次请求的时候,都要创建⼀个新的连接,⽽创建连接的过程需要消耗资源和时间,

为了减少资源消耗、缩短响应时间,就需要复⽤已有连接。

在后来的 HTTP/1.0 以及 HTTP/1.1 中引⼊了复⽤连接的机制,也就是在请求头中加⼊Connection: keep-alive,

以此告诉对⽅这个请求响应完成后不要关闭连接,下⼀次还⽤这个请求的连接进行后续交流。

协议规定,如果想要保持连接,则需要在请求头中加上 Connection: keep-alive。

keep-alive 的优点 (复用连接)

  • 较少的 CPU 和内存的占⽤(因为要打开的连接数变少了, 复用了连接)
  • 减少了后续请求的延迟(⽆需再进⾏握⼿)

缺点: 因为在处理的暂停期间,本来可以释放的资源仍旧被占用。请求已经都结束了, 但是还一直连接着也不合适

解决:Keep-Alive: timeout=5, max=100

  • timeout:过期时间5秒(对应httpd.conf里的参数是:KeepAliveTimeout),

  • max是最多一百次请求,强制断掉连接。

    就是在timeout时间内又有新的连接过来,同时max会自动减1,直到为0,强制断掉。

8. 为什么需要HTTPS?

HTTPS 是安全版的 HTTP。

HTTP 协议在传输数据时采用的是明⽂方式传递,因此,⼀些敏感信息的传输就变得很不安全。

而 HTTPS 就是为了解决 HTTP 的不安全⽽产⽣的。

9. HTTPS是如何保证安全的?

HTTPS 在传输数据的过程中会对数据进行加密处理,保证安全性。

那HTTPS采用的什么样的加密方式呢?我们来了解下一些加密的基本概念。

目前常见的加密算法可以分成三类,对称加密算法(可逆的),非对称加密算法(可逆的)和Hash算法(不可逆的)。

9.1 什么是对称加密?

对称加密的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥,

这种方法在密码学中叫做对称加密算法,对称加密算法使用起来简单快捷,密钥较短,且破译困难

通信的双⽅都使⽤同⼀个秘钥进⾏加解密。⽐如,两个人事先约定的暗号,就属于对称加密。

对称加密的特点是:

  • 优点:

    计算量小、加密速度快、加密效率高。

  • 缺点:

    在数据传送前,发送方和接收方必须商定好秘钥,然后双方保存好秘钥。

    如果一方的秘钥被泄露,那么加密信息也就不安全了

使用场景:本地数据加密、https通信、网络传输等

常见算法:AES、DES、3DES、DESX、Blowfish、IDEA、RC4、RC5、RC6

9.2 什么是⾮对称加密?

而加密和解密其实可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,

这样就避免了直接传递密钥。这种新的加密模式被称为"非对称加密算法"。

通信的双方使用不同的秘钥进行加密解密,即秘钥对(私钥 + 公钥)。

特征: 私钥可以解密公钥加密的内容, 公钥可以解密私钥加密的内容

非对称加密的特点是:

  • 优点:非对称加密与对称加密相比其安全性更好

  • 缺点:加密和解密花费时间长、速度慢,只适合对少量数据进行加密。

使用场景:https会话前期、CA数字证书、信息加密、登录认证等

常见算法:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)

9.3 HTTPS 加密解决⽅案

结合了两种加密⽅式:

  • 对称加密的密钥 ⽤非对称加密的公钥, 进⾏加密并发送出去,接收⽅使⽤私钥解密得到 对称加密密钥

  • 双⽅沟通时使⽤ 对称加密密钥 进⾏

可以看到,只有在发送秘钥阶段才使用非对称加密,而后续的通信都使用对称加密,这样解决了性能问题。

HTTPS 目前所使用的 TLS或SSL协议, 就是目前采用的加密通道的规范协议

它利用对称加密、(公私钥)非对称加密, 以及其密钥交换算法,可完成可信任的信息传输

9.4 数字证书

为了安全性, 一般还需要签发数字证书!

客户端 和 服务器端要初步互通消息时, 客户端发送请求可以拿到公开的公钥信息

进而进行非对称加密, 使用公钥, 加密对称加密密钥, 传递给服务器, 后续通信都使用对称加密!

问题是: 初步互通消息时, 如果请求拿到的公钥信息, 就是假的, 或者不安全的! 那么后续的所有操作, 都将是不安全的!

所以, 就需要有数字证书(CA证书), 一般是CA机构颁发的, 证明这个公钥是安全可靠的!

CA证书中心会对你网站的公钥, 网站的域名地址, 证书到期时间, 等一些相关信息一起加密签发数字证书, 保证你网站的安全性

当公司申请了 CA 证书后, 就应该在响应时, 将数字证书一起发送给客户端

而客户端, 接收到消息后, 就可以查看证书

  1. 如果正在访问的网站 和 证书记载的网址 不一致, 说明不安全, 可能被冒用, 浏览器就会发出警告!!!

  2. 如果签发证书的机构, 不权威, 发出警告

  3. 如果证书过期了, 浏览器也会发出警告

9.5 数字签名

但这还是有问题:如果证书被篡改了怎么办?

这时就需要用⼀个技术:数字签名。 (根据证书内容, 生成的一个唯一标识)

数字签名就是先⽤ CA ⾃带的 Hash 算法来计算出证书内容的⼀个摘要,然后使⽤ CA 私钥进行加密,组成数字签名。

当别⼈把他的证书发过来时,接收方⽤同样的算法再次⽣成摘要,⽤ CA 公钥解密后得到CA生成的摘要,两者进行对⽐后,

就能确定中间是否被⼈篡改。这样就能最⼤程度的保证通信的安全了。

10. HTTP2和HTTP1.x比,有什么优势和特点?

  1. HTTP/2 采⽤⼆进制格式来传输数据,⽽⾮ HTTP 1.x 的⽂本格式,⼆进制协议解析起来更⾼效
  2. HTTP/2 采用一些头部压缩技术,减少在请求和响应头中重复携带的数据,降低网络负担
  3. HTTP/2 采⽤服务器推送方式,主动向客户端推送资源,提高页面加载效率
  4. HTTP/2 采⽤多路复用机制,减少需要创建的连接数量,降低资源占用和性能消耗

下面是一些与之关联的技术知识。

⼆进制格式分帧

帧:HTTP/2 数据通信的最⼩单位消息,是指 HTTP/2 中逻辑上的 HTTP 消息(例如请求、响应等)。消息由⼀个或多个帧组成

流:存在于连接中的⼀个虚拟通道,它可以承载双向消息,且每个流都有唯⼀的整数ID

头部压缩

在 HTTP/1.x 中,请求和响应中会重复携带一些不常改变、冗⻓的头数据,给⽹络带来额外负担。

在 HTTP/2 中,客户端和服务端使⽤ “⾸部表” 来跟踪和存储之前发送过的键值对,

相同的数据不再随着每次请求和响应发送。⾸部表在连接存续期间始终存在,由客户端和服务器共同渐进更新。

每个新的⾸部键值对,要么被追加到当前表的末尾,要么替换表中已存在的键值对。

可以简单的理解为:只发送差异数据,⽽不是全部发送,从⽽减少头部的信息量

服务器推送

服务端可以在发送⻚⾯ HTML 内容时,再主动推送一些其它资源,⽽不⽤等到浏览器解析到相应的位置时发起请求后再作响应。

例如,服务端可以主动把 JS 和 CSS ⽂件推送给客户端,⽽不需要客户端解析 HTML 时再发送这些请求。

不过,服务端的主动推送行为,客户端有权利选择是否要接收。

如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送 RST_STREAM 帧来拒收。

多路复用

在 HTTP 1.x 中如果想并发多个请求的话,必须使⽤多个 TCP 链接,但浏览器为了控制资源,

会对单个域名有 6-8 个 TCP 链接的数量限制。而在 HTTP 2 中:

  • 同域名下的所有通信,都在单个连接上完成
  • 单个连接可以承载任意数量的双向数据流
  • 数据流以消息的形式发送,⽽消息⼜由⼀个或多个帧组成(多个帧可以乱序发送,因为可以根据帧⾸部的流标识来重新组装)

11. http缓存控制

11.1 基本认知

Web 服务缓存 大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 服务器缓存)、浏览器缓存。

浏览器缓存 也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。这里我们只讨论 HTTP 缓存相关内容

HTTP缓存:

  • 强缓存
  • 协商缓存

在具体了解 HTTP 缓存之前先来明确几个术语:

  • 缓存命中率:从缓存中得到数据的请求数 与 所有请求数的比率。理想状态是越高越好。
  • 过期内容:超过设置的有效时间,被标记为“陈旧”的内容。
  • 验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
  • 失效:失效就是把内容从缓存中移除。

浏览器缓存主要是 HTTP 协议定义的缓存机制。

浏览器缓存, HTTP缓存分类

浏览器缓存分为强缓存 协商缓存,浏览器加载一个页面的简单流程如下:

  1. 浏览器先根据这个资源的 http头信息判断是否命中强缓存

    如果命中则直接加载在缓存中的资源,并不会将请求发送到服务器。(强缓存)

  2. 如果未命中强缓存,则浏览器会将资源加载请求发送到服务器。

    服务器来判断浏览器本地缓存是否失效。

    若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源。(协商缓存)

  3. 如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。(新的请求)

11.2 强缓存 (食品过期时间判断)

(进行判断, 是否资源过期, 如果未过期, 直接用缓存)

强缓存

命中强缓存时,浏览器并不会将请求发送给服务器。

在Chrome的开发者工具中看到http的返回码是200,但是在Size列会显示为(from cache)。

强缓存是利用http的返回的响应头中的Expires或者Cache-Control (优先级更高) 两个字段来控制的,用来表示资源的缓存时间。

Expires: 指定一个具体时间(2020年12月12日 17:00), 到了这个时间了, 缓存过期了, 在时间内, 都是有效的, 可以直接读

Cache-Control : 指定一个过期时间 (3600s), 这个资源你加载到后, 可以用 3600s

Expires

缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires=max-age + 请求时间,需要和Last-modified结合使用。但在上面我们提到过,cache-control的优先级更高。

Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。

该字段会返回一个时间,比如Expires: Wed, 23 Nov 2050 16:00:01 GMT 。这个时间代表着这个资源的失效时间,也就是说在xx年xx月xx日时间之前都是有效的,即命中缓存。

这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当 服务器与客户端 时间偏差很大 以后,就会导致缓存混乱。于是发展出了Cache-Control。

Cache-Control

Cache-Control是一个相对时间,例如Cache-Control:max-age 3600,代表着资源的有效期是3600秒。

由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。

Cache-Control与Expires可以在服务端配置同时启用或者启用任意一个,同时启用的时候Cache-Control优先级高。

Cache-Control 可以由多个字段组合而成,主要有以下几个取值:

  1. max-age 指定一个时间长度,在这个时间段内缓存是有效的,单位是s。

    例如设置 Cache-Control:max-age=31536000,也就是说缓存有效期为(31536000 / 24 / 60 / 60)天,

    第一次访问这个资源的时候,服务器端也返回了 Expires 字段,并且过期时间是一年后。

    在没有禁用缓存并且没有超过有效时间的情况下,再次访问这个资源就命中了缓存,不会向服务器请求资源而是直接从浏览器缓存中取。

  2. no-cache 强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证的请求到服务器, 问服务器是否可以读缓存。

    不是字面意思上的不缓存。

  3. no-store 禁止缓存,每次请求都要向服务器重新获取数据。

注意:如果命中强缓存,在有效期内,使用了本地浏览器的缓存,不会向服务器发送请求的

11.3 协商缓存 (找供货商专家协商)

看看过期时间, 食品没过期, 直接吃 (直接读缓存, 不发请求) 强缓存

食品过期时间过了, 能不能吃呢? 问问专家(服务器), 专家瞅了一眼, 没过期 (响应304, 不返回内容) , 直接吃 (协商缓存)

如果问过专家(服务器), 专家瞅了一眼, 呀真过期了, 原来的不要了, 我重新给你发一个 (响应200, 并返回内容)

协商缓存

若未命中强缓存(强缓存过期了),则浏览器会将请求发送至服务器。

服务器根据http头信息中的Last-Modify/If-Modify-SinceEtag/If-None-Match来判断是否命中协商缓存。

如果命中,则http返回码为304 (你本地之前加载的资源是有效的),浏览器从缓存中加载资源。

Last-Modify/If-Modify-Since

浏览器第一次请求一个资源的时候, 服务器返回的header中会加上Last-Modify,

Last-modify是一个时间标识该资源的最后修改时间,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT

当浏览器再次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify

服务器收到If-Modify-Since后,根据实际服务器的资源的最后修改时间, 进行判断是否命中缓存。

如果命中缓存,则返回 http304,并且不会返回资源内容,并且不会返回Last-Modify。

由于对比的是服务端时间,所以客户端与服务端时间差距不会导致问题。

但是有时候通过最后修改时间来判断资源是否修改还是不太准确(资源变化了最后修改时间也可以一致)。

比如: 最后修改只能精确到秒级, 一秒进行了多次修改, 就不行了, 于是出现了ETag/If-None-Match。

ETag/If-None-Match

与Last-Modify/If-Modify-Since (最后修改时间)不同的是,Etag/If-None-Match返回的是一个校验码(ETag: entity tag)。

ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。

ETag值的变更则说明资源状态已经被修改。

服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。

ETag生成靠以下几种因子

  1. 文件的i-node编号,是Linux/Unix用来识别文件的编号。

  2. 文件最后修改时间

  3. 文件大小

生成Etag的时候,可以使用其中一种或几种因子,使用抗碰撞散列函数来生成。生成一个标记文件的唯一值

既生 Last-Modified 何生 Etag ?

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?

Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

  1. Last-Modified标注的最后修改只能精确到秒级

    如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间

  2. 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形

Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加 准确的控制缓存。

不会仅仅只根据最后的修改时间判断是否进行使用缓存

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,

最后才决定是否返回304。

小结:

  • 强缓存: 大大的减少了 服务器的请求次数, 在过期时间内, 直接从客户端内存中读

  • 协商缓存: 强缓存命中失效了, 超过过期时间了, 拿着标识(最后的修改时间, 唯一标识etag), 去问服务器, 是否真的过期了

    如果验证通过, 服务器会直接响应 304, 且不会返回资源

TCP协议

1. TCP协议是什么?

TCP(Transmission Control Protocol 传输控制协议) 是一种面向连接(连接导向) 的、可靠的、 基于IP的传输层协议。

TCP 使⽤校验、确认和重传机制来保证可靠传输

而 HTTP协议 就是建立在 TCP / IP 协议 之上的一种应用。

TCP: 三次握手, 四次挥手~

2. 一次完整的HTTP服务过程是什么

当我们在web浏览器的地址栏中输入:www.baidu.com,具体发生了什么?

  1. www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址
  2. 根据这个IP,找到对应的服务器,发起TCP的三次握手
  3. 建立TCP连接后, 发起HTTP请求
  4. 服务器响应HTTP请求,浏览器得到html代码
  5. 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)(先得到html代码,才能去找这些资源)
  6. 浏览器对页面进行渲染呈现给用户
  7. 服务过程完毕, 关闭TCP连接, 四次挥手

注:

1.DNS怎么找到域名的?

DNS域名解析采用的是递归查询的方式,过程是,先去找DNS缓存->缓存找不到就去找根域名服务器->根域名又会去找下一级,这样递归查找之后,找到了,给我们的web浏览器

2.为什么HTTP协议要基于TCP来实现?

TCP是一个端到端的可靠面相连接的协议,HTTP基于传输层TCP协议不用担心数据传输的各种问题(当发生错误时,可以重传)

3.最后一步浏览器是如何对页面进行渲染的?

a)解析html文件构成 DOM树
b)解析CSS文件构成渲染树
c)边解析,边渲染
d)JS 单线程运行,JS有可能修改DOM结构,意味着JS执行完成前,后续所有资源的下载是没有必要的,所以JS是单线程,会阻塞后续资源下载

3. 什么是DNS 解析

DNS解析(域名解析服务器) 将 域名 转换成 ip地址 (一个域名和ip的映射关系, 具体登记在哪里, 看我们如何申请关联的!)

假定请求的是 www.baidu.com

a)首先会搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存)

b)如果浏览器自身的缓存里面没有找到,那么浏览器会搜索系统自身的DNS缓存

c)如果还没有找到,那么尝试从 hosts 文件里面去找 (一个系统电脑的文件, 可以编辑, 可以存 域名 和 ip 的对应关系)

d)在前面三个过程都没获取到的情况下,就递归地去域名服务器去查找(就近查找),具体过程如下

DNS优化两个方面:DNS缓存、DNS负载均衡 (准备多台dns服务器, 进行dns解析)

4. TCP 三次握手理解 (双方确认)

TCP是一个端到端的 可靠 面相连接的协议,

HTTP基于传输层TCP协议不用担心数据传输的各种问题(当发生错误时,可以重传)

根据这个IP,找到对应的服务器,发起TCP的三次握手 (tcp 三次握手四次挥手 )

为什么要3次握手

我们假定第一次发送的请求, 因为网络延迟很慢才到达服务端,

然后客户端以为这服务器居然不理睬我,然后默默的关闭的等待连接的请求,走开了(好比追女神);

但事实呢?女神(服务器)是因为各种各样的原因,很晚才看到,然后说我接受你了, 同意你的要求咱们两结婚吧!

但是,A早已经远走高飞,这个请求A完全不会收到(在第二次握手,服务端打开连接,等待客户端的响应),

那么女生呢,以为对方收到了,就会一直等待,这样B的资源就会被浪费的(创建连接的时候,空间浪费以及端口消耗);

而三次握手, 就不会发生,服务端同意连接了,但是A缺一直没有下一步的动作,导致资源浪费;

5. 关闭TCP连接四次挥手的理解 (客气挽留)

目标: 关闭连接(四次挥手)

不能直接一次性断开连接(双方知晓), 万一还有什么数据没有传完, 造成数据的丢失!

1.一方发起断开连接信息

2.另一方会确认收到断开的需求,但是要求等待一会儿,确认数据是否传输完毕

3.当确认完毕之后,确实数据都传输完了,告知断开方,连接可以断开了

4.断开方确认收到消息

DMO

1. DOM的事件流是什么?

事件流

⼜称为事件传播,是⻚⾯中接收事件的顺序。DOM2级事件规定的事件流包括了3个阶段:

  • 事件捕获阶段(capture phase)
  • 处于⽬标阶段(target phase)
  • 事件冒泡阶段(bubbling phase)

事件流的触发顺序是:

  1. 事件捕获阶段,为截获事件提供了机会
  2. 实际的⽬标元素接收到事件
  3. 事件冒泡阶段,可在这个阶段对事件做出响应

事件冒泡(Event Bubbling)

事件开始由最具体的元素(⽂档中嵌套层次最深的那个节点)接收到后,开始逐级向上传播到较为不具体的节点。

<html>
  
  <head> 
    <title>Documenttitle> 
  head>
  
  <body> 
    <button>按钮button> 
  body> 
  
html>

如果点击了上面页面代码中的

你可能感兴趣的:(前端)