当前位置:   article > 正文

前端面试题总结 Vue篇_前端面试介绍vue项目经验

前端面试介绍vue项目经验

1、v-show和v-if区别的区别:

v-show通过css 的 display属性控制显示和隐藏,v-if 是创建和销毁,而不是显示和隐藏,频繁切换状态使用 v-show 否则 v-if,现在大多不用考虑性能问题,所以一般可以使用v-if

2、为何v-for要用key

快速查找到节点,减少渲染次数,提升渲染性能,防止渲染时因为dom结构顺序改变,出现渲染错误

3、组件的生命周期

组件的生命周期 指的是:组件从 创建 -> 运行(渲染) -> 销毁 的整个过程,强调的是一个 时间段

在组件的生命周期中,vue框架为组件内置了不同时刻的生命周期函数,生命周期函数会在组件运行的过程中自动调用,单组件生命周期函数有一下几种:

  1. beforeCreate: 组件实例刚刚被创建,属性和方法还未初始化。

  2. created: 组件实例被创建,属性和方法已经初始化,但是 DOM 还未渲染。

    可以在该节点进行数据的操作,比如发起请求获取数据

  3. beforeMount: 组件初次被渲染到页面之前。

  4. mounted: 组件被渲染到页面之后。

    可以在该节点,获取并操作dom结构。

  5. beforeUpdate: 组件更新前触发。

  6. updated: 组件更新后触发。

  7. beforeUnmount: 组件卸载前触发。

  8. unmounted: 组件卸载后触发。

    做一些清理性质的工作,如事件解绑,定时器清除

父子组件生命周期图

挂载: parent beforeCreate => parent created => parent beforeMount => child beforeCreate => child created => child beforeMount => child mounted => parent mounted
更新: parent beforeUpdate => child beforeUpdate => child updated => parent updated
销毁: parent beforeDestroy => child beforeDestroy => child destroyed => parent destroyed
从以上能够看出:
挂载时,子组件是在父组件before mount后开始挂载,并且子组件先mounted,父组件随后
更新时,子组件是在父组件before update后开始更新,子组件先于父组件更新
销毁时,子组件是在父组件before destroy后开始销毁,并且是子组件先销毁,父组件随后。

4、组件之间的数据共享

或者叫组件之间如何通信

组件之间的数据传递一共有六种方式。

1、父组件向子组件通过自定义属性传递参数

2、子组件向父组件通过自定义事件传递参数

3、父子组件使用 v-model指令进行进行双向数据绑定

4、兄弟组件之间通过 EventBus 进行传参

5、祖先组件向后代组件的传参,比如父组件通过 provide 方法将数据共享给子孙组件,子孙组件使用 inject数组进行接收。

6、vuex

(详细使用见 vue3 部分笔记)

5、vue组件的更新渲染过程

  1. 侦测变化:Vue 会通过依赖追踪机制检测组件的响应式数据是否发生变化。
  2. 执行更新函数:如果数据发生了变化,Vue 会调用组件的更新函数,该函数会计算新的虚拟 DOM(VNode)。
  3. 对比更新:Vue 会对比新旧 VNode,找出需要更新的节点,并将这些节点添加到待更新队列中。
  4. 批量更新:Vue 会在下一个 tick(即下一个事件循环)中批量更新组件,将待更新队列中的所有变化一次性地应用到真实 DOM 上。
  5. 渲染视图:更新后的真实 DOM 会被渲染到浏览器中,用户可以看到变化后的界面。

需要注意的是,在执行更新函数时,Vue 会对计算新的 VNode 进行优化,以提高渲染性能。其中,一个重要的优化手段是使用虚拟 DOM(Virtual DOM),通过比对新旧虚拟 DOM,避免不必要的 DOM 操作,减少了渲染的开销。

6、双向数据绑定 v-model 的实现原理

假设我们有一个 message 数据属性和一个输入框,我们希望在输入框中输入内容时,message 数据属性也会实时更新,而当修改 message 数据属性时,输入框中的值也会实时更新。我们可以使用 v-model 来实现这个功能。其功能在vue中的实现原理如下:

  1. 将输入框的值绑定到 message 数据属性上。

这个步骤相当于给输入框添加了一个 value 属性,这个属性的值等于 message 数据属性的值。同时,Vue 会监听输入框的 input 事件,当事件被触发时,会将输入框的值更新到 message 数据属性中。

这样,当我们在输入框中输入内容时,message 数据属性也会实时更新。

  1. message 数据属性的变化绑定到输入框的值上。

这个步骤相当于给输入框添加了一个 input 事件监听器,当 message 数据属性发生变化时,输入框的值也会自动更新。具体来说,当 message 数据属性的值发生变化时,Vue 会将新的值设置为输入框的 value 属性,从而实现输入框的实时更新。

7、 介绍一下mvvm

MVVM 是一种架构模式,全称为 Model-View-ViewModel

model:模型;view:视图;viewmodel:视图模型

核心是 viewmodel视图模型

视图模型是一个vue实例,负责将视图与数据模型进行双向绑定。当数据发生变化时,会自动更新视图。也就是数据驱动视图。而当用户操作视图时,ViewModel 也会自动更新数据模型。

总之,在 Vue 中,采用 MVVM 架构模式,通过 ViewModel 来实现数据双向绑定,让开发者只需关注数据模型的变化,而无需手动操作 DOM,提高了开发效率。同时,也使得应用程序更加易于维护和扩展。

8、computed有何特性

计算属性, 能够缓存数据,如果数据不变,不会重新计算。能够提高性能。

9、VUE 中什么是组件?如何封装组件?为什么要封装组件?组件中 data 为什么是一个函数?

  1. 什么是组件:在 Vue 中,组件(Component)是可复用的、独立的模块,用于构建用户界面。一个组件可以包含模板、脚本、样式等内容,可以接受外部传入的数据,同时也可以向外部发送事件。

  2. 如何封装组件:在实际开发中,我们可以根据业务需求,将一些通用的 UI 组件、业务组件等进行封装,提高代码复用性。

  3. 为什么要封装组件:减少重复代码的编写,提升开发效率和代码的可维护性。

  4. data 为什是一个函数:因为组件是可以复用的,多次使用同一个组件,每个实例都需要有自己的数据,如果定义为对象,所有实例共享一个数据对象,一个实例的数据变化便会影响到其他实例。定义成一个函数,每次使用组件时都会调用该函数返回一个新的数据对象。保证每个实例都有独立的数据。

10、多个组件有相同的逻辑怎么处理较好?

使用mixin 对公共部分的逻辑进行抽离,Mixin 是一种可重用的对象,可以包含一些组件中常用的逻辑和数据,然后将其混合到一个或多个组件中去。Mixin 可以用来在多个组件中共享代码,从而避免重复的代码,提高代码复用性和可维护性。

11、keep-alive的作用

缓存组件

12、何时使用beforeDestroy

做一些清理性质的工作时,如 解绑事件、清除定时器

13、什么是作用域插槽?

在使用插槽的时候可以利用插槽传输数据,绑定了自定义数据的插槽叫做作用域插槽,使用的时候在插槽的名字后面使用等号进行数据的接收。

14、介绍一下vuex

vuex 是一个专门为 vue 构建的状态管理工具,主要是为了解决 多组间之间状态共享问题。强调的是集中式管理,(组件与组件之间的关系变成了组件与仓库之间的关系)

核心概念如下:

state:数据源

Mutations:在该节点中定义方法操作 state 中的数据

Action:处理异步任务

Getter:类似与计算属性,对state中的数据进行加工处理,不会修改到state节点中的数据

15、vue-router常用路由模式

默认是 哈希模式(Hash mode)、第二种是 历史模式(History mode)需要后台服务器的支持

16、如何配置vue-router异步加载

在Vue.js中,我们可以通过Webpack的代码分割功能(Code Splitting)来实现路由组件的异步加载。异步加载可以提高应用程序的性能,因为它可以延迟加载不需要立即显示的路由组件,而只在需要时才加载它们。

要实现路由组件的异步加载,可以使用Webpack的动态import语法,如下所示:

const Foo = () => import('./Foo.vue')
  • 1

上面的代码使用箭头函数和import()语法来异步加载Foo.vue组件

接下来,我们可以在Vue Router的路由配置中使用这个异步加载的组件:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: () => import('./Foo.vue')
    }
  ]
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

上面的代码中,我们使用箭头函数和import()语法来异步加载Foo.vue组件,并将其作为路由组件的component选项。

如果是vue.js 2x 还需要进行一些额外的配置。

17、vue如何监听数据变化?

vue中的watch监听数据变化

18、vue的响应式原理

Vue 的响应式原理是通过利用 ES5 中的 Object.defineProperty() 方法来实现的。

当 Vue 初始化时,它会对 data 对象中的每个属性进行递归地遍历,并使用 Object.defineProperty() 将这些属性全部转换为 getter 和 setter。这样,当组件实例的数据发生变化时,就会自动触发 setter 函数,并通知依赖于该属性的所有组件进行重新渲染。

具体来说,当访问组件实例的一个属性时,例如 this.message,Vue 会通过 getter 方法进行拦截,并返回该属性的值。在同一个组件实例的模板中,如果使用了 {{ message }} 的语法,则 Vue 会自动将这个模板渲染函数添加到该属性的依赖列表中。当该属性的值发生变化时,Vue 就会通过 setter 方法进行拦截,并通知所有依赖于该属性的组件进行重新渲染。

这种基于 getter 和 setter 的响应式原理是 Vue 实现数据绑定和视图更新的核心机制。由于它只需要对每个属性进行一次遍历和转换,因此对于大规模的应用程序来说,它具有很高的性能和可维护性。

除了 Object.defineProperty() 方法,Vue 3 中还引入了新的响应式系统,它是基于 ES6 的 Proxy 对象实现的,相比于 Object.defineProperty(),它具有更好的性能和可扩展性,同时支持对 Map、Set 和 WeakMap 等数据结构的响应式处理。

19、vue为什么采用异步渲染? $nextTick有什么作用?

Vue 采用异步渲染的主要原因是为了提高渲染效率和性能。当 Vue 组件更新时,它会触发一系列的操作,包括重新计算虚拟 DOM 树、比较新旧虚拟 DOM 树的差异、更新实际 DOM 树等等,这些操作可能会消耗大量的时间和计算资源。为了避免这些操作对应用程序的响应性产生影响,Vue 采用了异步渲染的策略,将这些操作放在事件循环的下一个 tick 中执行,使得组件更新不会阻塞主线程,提高了用户体验。

在 Vue 中,$nextTick 方法是用来在下一个 tick 中执行一个回调函数的,该回调函数会在当前组件更新完成后被执行。由于 Vue 采用了异步渲染的策略,因此在某些情况下,如果我们想要在组件更新完成后执行一些操作,就需要使用 $nextTick 方法来确保这些操作能够正确地执行。例如,在组件的 mounted 钩子函数中,我们可能需要获取组件的实际 DOM 元素的尺寸或位置等信息,这些信息只有在组件更新完成后才能够正确地获取,因此我们需要在 $nextTick 回调函数中执行这些操作。

下面是一个示例代码,演示了如何使用 $nextTick 方法:

export default {
  data() {
    return {
      message: 'Hello, world!',
      width: 0,
      height: 0
    }
  },
  mounted() {
    // 获取组件的实际宽度和高度
    this.$nextTick(() => {
      const el = this.$el
      this.width = el.offsetWidth
      this.height = el.offsetHeight
    })
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

再通俗的解释一下这里的 tick 表示什么意思,为什么叫 tick?

在计算机中,tick 表示系统的一个基本时间单位,通常等于几十毫秒或几毫秒。每个 tick 的时间长度取决于操作系统和硬件平台,不同的系统和平台可能有不同的定义。在 JavaScript 中,tick 的含义稍有不同,通常表示 JavaScript 引擎中一次完整的事件循环(event loop)周期,也就是说,一次 tick 表示 JavaScript 引擎处理完所有当前存在的任务,然后开始处理下一轮异步任务的过程。

在 Vue 中,异步任务一般是在下一个 tick 执行的,这意味着当一个组件的数据发生变化时,Vue 并不会立即更新视图,而是在当前的 tick 结束后才会进行更新。这样做的好处是可以避免频繁地更新视图,提高渲染效率和性能,同时还可以避免一些常见的问题,比如数据更新时视图更新不同步、事件处理函数不立即响应等。

因此,Vue 中的 tick 具体指的是 JavaScript 引擎中的一次完整事件循环周期,通常表示在当前 tick 结束后执行的下一轮异步任务。通过将组件更新操作放在下一个 tick 中执行,Vue 实现了高效的异步渲染机制,保证了组件的渲染效率和性能。

20、vue中常见的性能优化方法

1、使用 v-if 和 v-for 指令时需要注意:

不要同时使用 v-if 和 v-for,因为它们的优先级不同,同时使用可能导致性能问题。

在使用 v-for 时,需要设置唯一的 key 值来提高性能。

2、使用 computed 属性或 watch 监听器来监听数据变化,以避免不必要的渲染和计算。

3、对于一些静态组件或内容,可以使用 v-once 指令(标记某个元素或组件只渲染一次)来进行缓存,以避免重复渲染。

4、使用异步组件来延迟加载页面,提高首屏加载速度。

5、对于一些长列表或大数据集合,可以使用虚拟滚动或分页加载等技术来优化性能,避免一次性加载大量数据。

6、使用 Webpack等工具进行代码压缩和打包,以减小文件体积和加载时间。

7、前端通用的性能优化措施:如图片的懒加载、减少HTTP的请求次数等。

21、vue.js的两个核心是什么?

数据驱动和组件化

22、vue中子组件调用父组件的方法?

1.直接在子组件中通过this.$parent.event来调用父组件的方法。

<template>
  <button @click="handleClick">调用父组件方法</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      this.$parent.handleCustomEvent()//调用父组件中的方法
    }
  }
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。

3.父组件使用 provide 把方法传入子组件中,在子组件里通过inject接收并直接调用这个方法。
① 父组件向子组件通过 provide 传递数据或方法

<template>
  <div>
    <child-component></child-component>
  </div>
</template>

<script>
export default {
  provide: {
    parentMethod: this.handleCustomEvent
  },
  methods: {
    handleCustomEvent() {
      // 父组件中的方法逻辑
    }
  }
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

② 在子组件中通过 inject 注入父组件中提供的数据或方法

<template>
  <button @click="handleClick">调用父组件方法</button>
</template>

<script>
export default {
  inject: ['parentMethod'],
  methods: {
    handleClick() {
      this.parentMethod()
    }
  }
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

23、父组件调用子组件中的方法

通过 ref 引用获取子组件的实例,通过该实例直接调用子组件中的方法。

24、vue页面级组件之间传值?

1.使用vue-router通过跳转链接带参数传参。

2.使用本地缓存localStorge。

3.使用vuex数据管理传值

25、说说vue的动态组件。

多个组件通过同一个挂载点进行组件的切换,is的值是哪个组件的名称,那么页面就会显示哪个组件。

26、$route$router的区别是什么?

$router为VueRouter的实例,是一个全局路由对象,包含了路由跳转的方法、钩子函数等。

$route 是路由信息对象。每一个路由都会有一个route对象,是一个局部对象,包含path,params,hash,query,fullPath,matched,name等路由信息参数。

27、vue中哪些数组方法可以直接对数组修改实现视图更新

push() pop() shift() unshift() splice() sort() reverse() vue数组对象修改触发视图更新

28、使用过keep-alive吗

keep-alive缓存vue实例,提高性能是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 ,提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高;对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。

29、computed、watch、methods区别

在 Vue 中,computed、watch、methods 都是用于处理数据逻辑的方法,但它们之间的区别如下:

  1. computed:计算属性是一个基于响应式依赖进行缓存的属性。当其依赖的数据发生变化时,计算属性会重新计算,并将计算结果缓存起来,直到其依赖的数据再次发生变化。计算属性适用于依赖其他数据进行计算的场景。

  2. watch:是一个监听数据变化并执行回调函数的方法。可以通过 watch 方法监听一个数据的变化,并在数据变化时执行相应的回调函数。适用于监听某个数据的变化并作出相应的响应,例如异步请求数据。

  3. methods:方法是一段可以执行的代码块,可以在模板或其他方法中调用。方法适用于需要执行一些逻辑的场景,例如点击事件处理函数、表单提交处理函数等。

30、什么是$nextTick?

vue是异步渲染的框架,data改变之后,dom不会立刻渲染,$nextTick会在dom渲染之后被触发,以获取最新dom节点

31、ref 的作用?

获取dom元素,或者是获取子组件的实例。使用:this.$refs.自定义的引用名称

32、路由传参的方式有哪些?

1、动态路由传参:在路由定义时使用冒号(:)来定义动态参数,例如:

{
  path: '/user/:userId',
  component: User
}
  • 1
  • 2
  • 3
  • 4

在组件内可以通过 $route.params 来访问动态路由参数:

export default {
  mounted() {
    const userId = this.$route.params.userId
    // 对 userId 进行操作
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、查询参数传参:在路由中使用查询字符串(?)来定义参数,例如

{
  path: '/user?userId=1',
  component: User
}
  • 1
  • 2
  • 3
  • 4

在组件内可以通过 $route.query 来访问查询参数:

export default {
  mounted() {
    const userId = this.$route.query.userId
    // 对 userId 进行操作
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3、路由元信息传参:在路由定义时可以添加一些额外的元信息来传递参数,例如:

{
  path: '/user',
  component: User,
  meta: {
    userId: 123
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在组件内可以通过 $route.meta 来访问路由元信息:

export default {
  mounted() {
    const userId = this.$route.meta.userId
    // 对 userId 进行操作
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4、编程式导航传参:使用 router.push() 方法进行编程式导航时,可以在第二个参数中传递参数,例如:

this.$router.push({ path: '/user', query: { userId: 123 }})
  • 1

在组件内可以通过 $route.query 来访问传递的参数。

33、介绍一下axios、axios拦截器

Axios是一个基于 promise 的专注于实现网络数据请求的 HTTP 库

axios拦截器可以实现对请求和响应的全局拦截和处理,包括请求拦截器(在请求发出之前进行拦截处理)和响应拦截器(在响应接收前进行拦截处理)

请求拦截器:axios.interceptors.request.use()

响应拦截器:axios.interceptors.response.use()

拦截器中可以做一些操作,比如添加一个加载样式,对请求头进行一些配置等。

34、介绍一下如何解决跨域问题

在项目中配置 proxy代理(在开发调试阶段使用),在服务器端配置 cors 跨域资源共享

35、为什么做首屏优化?首屏优化的方式有哪些?

首屏时间的快与慢,直接影响到了用户对网站的认知度。所以首屏时间的长短对于用户的滞留时间的长短、用户转化率都尤为重要。

在 Vue 项目中,可以采取以下几种方式来进行首屏优化:

  1. 按需引入第三方库:Vue 项目中引入第三方库时,一定要注意只引入需要使用的部分,减少无用的代码和文件体积,可以通过 Tree shaking 或按需引入来实现。

  2. 代码分割和按需加载:将项目代码分割成多个小模块,按需加载,而不是一次性加载所有的代码,可以大幅度减少首屏加载时间,提升用户体验。Vue CLI 中默认使用了 code-splitting 技术。

  3. 使用缓存:合理利用浏览器缓存,缓存公共文件和静态资源文件,可以减少服务器的请求次数,提升页面加载速度。

  4. 图片懒加载:在 Vue 项目中使用图片懒加载技术,只有在用户滚动到图片位置时才加载图片,而不是一次性加载所有图片,可以加速首屏加载时间,提升用户体验。

  5. 服务端渲染(SSR):使用 SSR 技术可以让用户在请求页面时,就直接从服务器获取已经渲染好的 HTML 文件,提升首屏渲染速度。Vue 官方提供了 Vue SSR 框架。

  6. 优化代码:Vue 项目中代码优化也是重要的一环,优化代码结构,减少重复代码,使用 Vue 内置的优化指令和组件,减少页面的计算量和重新渲染次数,可以提升页面性能和响应速度。

36、vue常用的修饰符

.stop - 调用 event.stopPropagation(),禁止事件冒泡。

.prevent - 调用 event.preventDefault(),阻止事件默认行为。

.capture - 添加事件侦听器时使用 capture 模式。

.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。

.native - 监听组件根元素的原生事件。

.once - 只触发一次回调。

v-model 指令常用修饰符:

.number - 输入字符串转为数字

.trim - 输入首尾空格过滤

.lazy-绑定之后数据延迟更新,比如输入框,不使用该修饰符的时候,输入框中的内容只要一改变就会立马更新data中的数据(比如数据为 message )。加上该修饰符后,当输入框失去焦点后才会同步数据。

37、vue中如何监听键盘事件中的按键

在监听键盘事件时,我们经常需要判断用户按下的是哪一个按键。此时,可以为键盘相关的事件添加按键修饰符,例如:

<input @keyup.enter="submit">
  • 1

38、介绍一下vue的单页面应用程序及其优缺点

Vue的单页面应用程序(Single Page Application,SPA)指的是在一个页面内使用Vue进行动态渲染,以实现前端路由、组件化等特性的Web应用程序。与传统的多页面应用程序相比,Vue的单页面应用程序有以下优缺点:

优点:

  1. 更快的页面切换:因为Vue的单页面应用程序只在初始化时加载一次,之后只需要加载必要的数据和组件,所以在页面切换时不需要重新加载整个页面,从而实现更快的页面切换。

  2. 更好的用户体验:Vue的单页面应用程序可以实现更流畅、更快速的用户体验,因为在切换页面时不需要重新加载整个页面,而是只需要切换组件,从而减少了页面的闪烁和卡顿现象。

  3. 更高的开发效率:Vue的单页面应用程序使用组件化的开发方式,可以将整个应用程序拆分成多个组件,每个组件都可以独立开发、测试和调试,从而提高了开发效率和代码质量。

缺点:

  1. 初次加载时间长:因为Vue的单页面应用程序需要加载所有必要的组件和数据,所以初次加载时间会比较长,特别是对于一些复杂的应用程序来说,需要加载的内容更多,加载时间更长。

  2. 对浏览器的兼容性要求高:Vue的单页面应用程序需要使用一些新的浏览器技术,比如HTML5、CSS3、ES6等等,所以对浏览器的兼容性要求比较高,对一些低版本的浏览器可能无法兼容。

  3. 不利于SEO优化:尽管Vue的单页面应用程序可以实现更好的SEO优化,但是对于一些需要SEO优化的应用程序来说,可能还需要额外的SEO优化工作,比如使用预渲染技术等等,从而提高网站在搜索引擎上的排名。

39、从URL到页面呈现的全过程

  1. DNS解析:浏览器根据URL中的域名,通过DNS解析获取服务器的IP地址

  2. 建立TCP连接:浏览器与服务器建立TCP连接。这个过程涉及到TCP协议中的三次握手,确保客户端与服务器之间的连接稳定可靠。

  3. 发送HTTP请求:浏览器向服务器发送HTTP请求。获取服务器端的资源

  4. 服务器响应:客户端获取到资源

  5. TCP四次挥手关闭客户端和服务器的连接

  6. 浏览器解析文档资源并渲染页面

浏览器解析文档资源并渲染页面流程:

(1)解析html资源,构建DOM Tree

(2)解析css资源,构建CSS Rule Tree

(3)JS通过DOM API和CSSOM API来操作DOM Tree和CSS Tree

(4)解析完成后综合DOM Tree和CSS Tree会生成Render Tree,计算每个元素的位置,这个过程就是回流(layout or reflow)

(5)调用操作系统Native GUI的绘制

(6)页面绘制完成

TCP建立连接的三次握手:

  1. 客户端发送 SYN 包:客户端向服务器发送一个 SYN(同步)包,表示客户端请求连接。该包中包含一个随机生成的序列号 A。

  2. 服务器发送 SYN+ACK 包:服务器接收到 SYN 包后,向客户端回送一个 SYN+ACK(同步+确认)包。该包中包含服务器随机生成的序列号 B,以及确认号 A+1(表示客户端的 SYN 包已经收到)。此时,服务器进入 SYN_RCVD 状态,等待客户端的确认。

  3. 客户端发送 ACK 包:客户端收到 SYN+ACK 包后,向服务器发送一个 ACK(确认)包。该包中包含客户端确认号 B+1(表示服务器的 SYN+ACK 包已经收到)。此时,客户端进入 ESTABLISHED(已连接)状态,服务器收到该包后也进入 ESTABLISHED 状态,此时连接建立成功。

简单理解:① 客户端向服务器发送一个请求包;② 服务器收到后向客户端发送一个包表示收到,③ 客户端收到后返回一个确认包,表示知道服务器端收到了

客户端:请求链接

服务器:知道了

客户端:我知道你知道了

TCP断开链接的四次挥手:

TCP四次挥手是TCP连接的关闭过程,由连接的任何一方都可以发起。四次挥手过程如下:

  1. 主动关闭方发送FIN包:当客户端决定关闭连接时,它向服务器发送一个FIN包,表示它不会再向服务器发送数据。

  2. 被动关闭方发送ACK包:服务器收到客户端发送的FIN包后,发送一个ACK包,表示已经收到客户端发来的FIN包,并确认该包中的序列号。

  3. 被动关闭方发送FIN包:当服务器也准备关闭连接时,它向客户端发送一个FIN包,表示它不会再向客户端发送数据。

  4. 主动关闭方发送ACK包:客户端收到服务器发送的FIN包后,向服务器发送一个ACK包,表示已经收到服务器发来的FIN包,并确认该包中的序列号。

简单理解,比如客户端主动发送断开链接请求

客户端:不要数据了(不再向服务器发送数据)

服务器:收到

服务器:准备断开链接 (不再向客户端发送数据)

客户端:了解,over!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/132622
推荐阅读
相关标签
  

闽ICP备14008679号