切换语言为:繁体

前端开发面试题精选(包括HTML/CSS/JavaScript/Vue/HTTP)

  • 爱糖宝
  • 2024-09-20
  • 2051
  • 0
  • 0

一、移动端怎么做适配?

面试官问你这个问题其实就是想问你响应式布局,实现响应式布局的方式有哪些?

1. 使用媒体查询(Media Queries)

媒体查询是 CSS3 中引入的一种方式,可以针对不同的设备或屏幕尺寸应用不同的样式规则。通过媒体查询,可以编写响应式的 CSS,使页面在不同设备上呈现最佳视觉效果。

例如:

/* 默认样式 */
body {
  font-size: 16px;
}

/* 屏幕宽度小于600px时的样式 */
@media screen and (max-width: 600px) {
  body {
    font-size: 14px;
  }
}

/* 屏幕宽度大于1200px时的样式 */
@media screen and (min-width: 1200px) {
  body {
    font-size: 18px;
  }
}

2. 使用百分比单位

使用百分比单位而不是固定单位(如 px)可以使布局更加灵活,更容易适应不同尺寸的屏幕。

<div style="width: 100%;">
  <div style="width: 50%;">Half of the container's width</div>
  <div style="width: 50%;">Another half</div>
</div>

3. 使用视窗单位(Viewport Units)

视窗单位(vw、vh、vmin、vmax)根据视口(viewport)的大小来确定长度,非常适合用于响应式设计。

  • 1vw 等于视口宽度的 1%。

  • 1vh 等于视口高度的 1%。

  • 1vmin 等于视口宽度或高度中较小的一个的 1%。

  • 1vmax 等于视口宽度或高度中较大的一个的 1%。

body {
  font-size: 2vw; /* 字体大小为视口宽度的 2% */
}

.container {
  height: 50vh; /* 高度为视口高度的一半 */
}

4. 使用 REM 单位

REM(root em)单位相对于根元素(即 html 元素)的字体大小。设置 html 的字体大小,然后使用 REM 作为其他元素的大小单位,可以实现全局统一的缩放。

html {
  font-size: 16px; /* 默认字体大小 */
}

body {
  font-size: 1rem; /* 等于 16px */
}

@media screen and (max-width: 600px) {
  html {
    font-size: 12px; /* 在小屏幕上缩小字体大小 */
  }
}

h1 {
  font-size: 2rem; /* 等于 32px (默认情况下) */
}

5. 使用 Flexbox 或 Grid 布局

Flexbox 和 Grid 布局提供了强大的布局工具,可以轻松实现复杂的响应式布局。

/* Flexbox */
.container {
  display: flex;
  flex-wrap: wrap;
}

.item {
  flex-basis: 50%; /* 每个项目占据一半的宽度 */
}

/* Grid */
.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

.item {
  /* 项目样式 */
}

三、rem单位是怎么计算的?

rem(root em)单位是 CSS 中的一种相对单位,它相对于文档的根元素(通常是 <html> 元素)的字体大小来计算长度。rem 单位的主要优点在于它提供了一种全局的相对尺寸,使得整个页面的布局可以统一缩放。

rem 单位的计算方式

  1. 基本概念

    • em 单位相对于父元素的字体大小。

    • rem 单位相对于根元素(通常是 <html>)的字体大小。

  2. 计算公式

    • 如果根元素的字体大小为 font-size,那么 1rem 就等于 font-size 的值。

    • 如果某个元素的 font-size 设置为 2rem,那么它的字体大小就是根元素字体大小的两倍。

使用 rem 单位的好处:

  1. 全局一致性:在整个页面中使用相同的基准字体大小,可以保持样式的一致性。

  2. 易于维护:只需要更改根元素的字体大小即可调整整个页面的布局。

  3. 响应式设计:结合媒体查询和 JavaScript 动态调整,可以实现更精细的响应式设计。

四、了解less和sass吗

在前端开发中,LESS 和 SASS(Syntactically Awesome Style Sheets)都是预处理器语言,用于扩展 CSS 的功能,使得 CSS 更加模块化、可维护和强大。预处理器语言允许你在 CSS 中使用变量、嵌套规则、混合(mixins)、函数等功能,从而简化 CSS 的编写和管理。

LESS

LESS 是一种基于 JavaScript 的 CSS 预处理器。LESS 代码可以在客户端(浏览器)或服务器端运行,将 LESS 代码编译成普通的 CSS。LESS 的语法接近 CSS,并且易于学习和使用。

LESS 的特点:

1、变量

  • 定义变量来存储颜色、尺寸等常用值,方便复用和修改。

  • 示例:

    @primary-color: #ff0000;
    .header {
      color: @primary-color;
    }

2、嵌套选择器

  • 支持嵌套选择器,使得 CSS 规则更易读。

  • 示例:

.container {
  .header {
    color: red;
  }
  .content {
    padding: 10px;
  }
}

3、混合(Mixins)

  • 定义一组属性,可以像函数一样调用。

4、操作符

  • 支持数学运算。

5、函数

  • 可以定义函数来执行复杂的操作。

6、导入

  • 可以导入其他 LESS 文件。

SASS

SASS 是另一种流行的 CSS 预处理器。SASS 有两种语法格式:SCSS(Sassy CSS)和原生 SASS。SCSS 语法类似于 CSS,并且支持 CSS 的所有特性加上 SASS 的增强功能。原生 SASS 语法则完全不同,使用缩进来表示嵌套。

SCSS 特点:

1、变量

  • 与 LESS 类似,可以定义和使用变量。

  • 示例

$primary-color: #ff0000;
.header {
  color: $primary-color;
}

2、嵌套选择器

  • 支持嵌套选择器。

3、混合(Mixins)

  • 可以定义和使用混合。

4、操作符

  • 支持数学运算。

5、函数

  • 可以定义函数来执行复杂的操作。

6、导入

  • 可以导入其他 SASS 文件。

总结

LESS 和 SASS 都是非常有用的 CSS 预处理器,它们提供了许多强大的功能,如变量、嵌套、混合、函数等,使得 CSS 的编写更加高效和可维护。选择哪个预处理器主要取决于个人或团队的偏好以及项目的具体需求。如果你熟悉 JavaScript,可能更倾向于使用 LESS;如果你喜欢简洁的语法,可能会更喜欢 SASS(尤其是 SCSS)。无论选择哪一个,都可以显著提高前端开发的效率和代码质量。

五、v-model的实现原理

v-model 是 Vue.js 框架提供的一个指令,用于实现表单元素与 Vue 实例数据之间的双向数据绑定。 它的原理是: 在模板中使用 v-model 指令绑定表单元素的 value 属性(例如 input、textarea、select 等)到 Vue 实例中的一个属性。

当用户在表单元素中输入内容时,该元素的 value 值会被更新,并触发 oninput 事件。

Vue.js 监听该元素的 oninput 事件,并通过新旧值的比较来确定数据是否发生了变化。

如果数据已经发生变化,则更新 Vue 实例中绑定的属性值,从而实现数据的双向绑定。

如果用户在表单元素中按下回车键或者失去焦点,则该元素的 onchange 事件也会触发。Vue.js 同样监听该事件,并在事件处理函数中将表单元素的值同步到 Vue 实例中。

综上,v-model 的双向绑定原理就是通过在模板中绑定表单元素的 value 属性和监听表单元素的 input 和 change 事件来实现的。它可以大大简化开发人员对表单数据的处理和管理,使得代码更加简洁易读。

一、v-model双向绑定原理 1、v-model是v-on和v-bind的语法糖 v-on用于事件绑定,给当前组件绑定一个input事件。 v-bind用于属性绑定,给当前组件绑定一个value属性。 2、v-model双向绑定的实现: (1)在父组件内给子组件添加v-model,相当于给组件添加了个value 属性,传递的值就是绑定的值。和绑定了一个此绑定值的input事件。 (2)子组件中使用prop属性接受这个value值,名字必须是value。 (3)子组件内部更改value值的时候,必须通过$emit()事件派发个input事件,并携带最新的值。 (4)v-model绑定的input事件会自动监听这个input事件,把接收到的最近新值赋值给v-model绑定的变量。

六、vue的响应式原理

vue3的响应式原理

在Vue2的响应式中,存在着新增属性,删除属性以及直接通过下标修改数组,但页面不会自动更新的问题。但是在Vue3中,这些问题都得以解决。

实现原理: 通过Proxy(代理): 拦截对象中任意属性的变化,包括:属性值的读写,属性的增加,属性的删除等。

通过Reffect(反射): 对源对象的属性进行操作

new Proxy(data,{
  //拦截读取属性值
  get(target, prop){
    return Reflect.get(target, prop)
  },
  //拦截设置属性值或添加新属性
  set(target, prop, value){
    return Reflect.set(target, prop, value)
  },
  //拦截删除属性
  deleteProperty(target, prop){
    return Reflect.deleteProperty(target, prop)
  }
})

proxy

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

被 Proxy 代理虚拟化的对象。它常被作为代理的存储后端。根据目标验证关于对象不可扩展性或不可配置属性的不变量(保持不变的语义)。

语法

const p = new Proxy(target, handler)

参数: target: 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

handler: 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

Vue2中的响应式原理

首先我们先看一下Vue2中的响应式原理,其次我们在过渡到Vue3的响应式原理。

实现Vue2响应式是通过Object.defineProperty()来实现的,同样使用数据劫持的方法。

let person = {
            name:'路飞',
            age:18
        }

let p = {}
Object.defineProperty(p, "name", {
    get(){      //有人读取name时调用
        return person.name;
    },
    set(value){      //有人修改name时调用
        console.log("有人修改了name属性")
        person.name = value
    }
});

Object.defineProperty(p, "age", {
    get(){      //有人读取age时调用
        return person.age;
    },
    set(value){      //有人修改age时调用
        console.log("有人修改了age属性")
        person.age = value
    }
});

此时,p对象就完成了对person对象的代理,当读取p.name时,实际上是在读取person.name,当修改p.name时,实际上person中name属性的值也会随之更新。

但是,在Vue2中,无法通过p对象对person对象进行增和删的操作,实际上person对象是捕获不到的,所以即便通过p对象删除和增加属性,person对象内的属性是不会更新的。

七、vue3的组件通讯

1、父子组件间通信

1、子组件通过 props 属性来接受父组件的数据,然后父组件在子组件上注册监听事件,子组件通过 emit 触发事件来向父组件发送数据。

父子:父子组件通讯,父组件将值v-bind绑定传给子组件,组件使用defineProps接受。利用 watch 函数监听 props.msg 的变化。每当 msg 的值发生变化时,回调函数会被触发,新值 (newVal) 会被推送到 list 数组中。这意味着每当父组件通过 msg 属性传递一个新的值,这个值就会被添加到子组件的列表中。

子父:子父组件通讯,子组件通过defineEmits(["add1"])创建一个自定义事件,并通过emits("add1",value.value)传递数据给父组件。父组件则可以在使用子组件的标签上通过v-on来监听这个事件。

2、通过 ref 属性给子组件设置一个名字。父组件通过 r e f s 组件名来获得子组件,子组件通过 refs 组件名来获得子组件,子组件通过 parent 获得父组件,这样也可以实现通信。

3、使用 provide/inject,在父组件中通过 provide提供变量,在子组件中通过 inject 来将变量注入到组件中。不论子组件有多深,只要调用了 inject 那么就可以注入 provide中的数据。

2、跨代组件间通信

跨代组件间通信其实就是多层的父子组件通信,同样可以使用上述父子组件间通信的方法,只不过需要多层通信会比较麻烦。

1、provide / inject——使用 provide/inject,在父组件中通过 provide提供变量,在子组件中通过inject来将变量注入到组件中。不论子组件有多深,只要调用了 inject 那么就可以注入 provide中的数据【无响应性且只能单向通信(父传子)】 2、 a t t r s / attrs / listeners——具有响应性且可以双向通信

使用上述的6种方法的 a t t r s / attrs / listeners方法。

3、兄弟组件间通信

通过 p a r e n t + parent + refs 以父组件为中间人来获取到兄弟组件,也可以进行通信。

4、任意组件间通信

1、vuex状态管理——vuex 的思想就是将这一些公共的数据抽离出来,将它作为一个全局的变量来管理,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的

2、使用 eventBus ,其实就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。它的本质是通过创建一个空的 Vue 实例来作为消息传递的对象,通信的组件引入这个实例,通信的组件通过在这个实例上监听和触发事件,来实现消息的传递。

如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候采用上面这一些方法可能不利于项目的维护。这个时候可以使用 vuex ,vuex 的思想就是将这一些公共的数据抽离出来,将它作为一个全局的变量来管理,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。

八、vuex和pinia的区别

Vuex和Pinia都是Vue.js的状态管理工具,但它们在设计、使用、功能等方面存在一些区别。以下是它们之间主要区别的详细比较:

  1. 设计和使用 Vuex:采用全局单例模式,通过一个store对象来管理所有的状态,组件通过store对象来获取和修改状态1。Vuex的设计相对传统,适合大型和复杂的项目,提供了丰富的功能如模块化、插件和严格模式等12。 Pinia:采用了分离模式,每个组件都拥有自己的store实例,通过在组件中创建store实例来管理状态1。Pinia的设计更加现代和灵活,旨在提供一种更直观、更易于使用的方式来管理Vue应用的状态3。

  2. 数据修改 Vuex:包含mutations和actions,mutations用于同步修改状态,actions用于处理异步操作2。 Pinia:没有mutations,只有state、getters和actions1。Pinia的actions可以直接修改状态,而不需要像Vuex那样通过mutations来修改状态。

  3. 模块化 Vuex:支持模块化,可以将状态管理逻辑分割到不同的模块中4。 Pinia:也支持模块化,但每个独立的仓库都是通过defineStore生成的,提供了扁平化的结构,有助于更好的代码分割1。

  4. 语法和使用 Pinia:语法上比Vuex更容易理解和使用,提供了更好的TypeScript支持1。Pinia与Vue 3的Composition API紧密结合,允许将状态逻辑作为可复用的函数组合起来3。 Vuex:Vuex的语法和用法相对传统,对于熟悉Vue 2的开发者来说可能更加熟悉4。

  5. 体积和性能 Pinia:体积较小,约1KB,且性能较好,因为它使用了新的ES6语法和新的数据处理方式1。 Vuex:体积相对较大,但性能稳定可靠,是Vue.js官方提供的状态管理库2。

  6. 社区支持和适用场景 Vuex:是Vue.js官方出品,社区支持较强,拥有丰富的文档和示例,适合复杂的项目和对状态管理有更高要求的开发者12。 Pinia:是一个较新的框架,社区支持相对较弱,但它在Vue 3的Composition API生态中得到了官方支持,更适合初学者和快速开发项目13。

    总结 Vuex和Pinia都是Vue.js的状态管理工具,但它们在设计和使用上存在差异。Vuex是一个更完整的状态管理库,提供了丰富的功能和良好的社区支持,适合大型和复杂的项目。而Pinia则是一个轻量级的状态管理库,专注于提供一个简单的API来管理应用程序的状态,适合初学者和快速开发项目。在选择时,可以根据项目的具体需求和使用的Vue版本来决定使用哪一个。

九、如何实现水平垂直居中

这个是css中经常会被面试官问到的问题,有时候面试官还会让你手写,大家一定要背出来

情景:两个方块,大的包含小的,让小的水平垂直居中

方法一:定位absolute+translate

给top和left分别一个50%,然后自身再top和left负50%

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 500px;
            height: 500px;
            background-color: rgb(28, 101, 164);
            position: relative;
        }
        .wrap {
            width: 200px;
            height: 200px;
            background-color: green;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            /* margin-top: -100px; */
            /* margin-left: -100px; */
        }
    </style>
</head>
<body>
    <div>
        <div></div>
    </div>
</body>
</html>

如果已知宽高的时候也可以不用translate,直接写成margin-left:-100px和margin-top:-100px.

方法二:定位+margin auto

<style>
    .father{
        width:500px;
        height:300px;
        border:1px solid #0a3b98;
        position: relative;
    }
    .son{
        width:100px;
        height:40px;
        background: #f0a238;
        position: absolute;
        top:0;
        left:0;
        right:0;
        bottom:0;
        margin:auto;
    }
 </style>
 <div class="father">
    <div class="son"></div>
 </div

父级设置为相对定位,子级绝对定位,并且四个定位属性的值都设置了0,那么这时候如果子级没有设置宽高,则会被拉开到和父级一样宽高

这里子元素设置了宽高,所以宽高会按照我们的设置来显示,但是实际上子级的虚拟占位已经撑满了整个父级,这时候再给它一个margin:auto它就可以上下左右都居中了。

方法三:弹性布局flex

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 500px;
            height: 500px;
            background-color: rgb(28, 101, 164);
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .wrap {
   width: 200px;
            height: 200px;
            background-color: green;
        }
    </style>
</head>
<body>
    <div>
        <div></div>
    </div>
</body>
</html>

justify-content: center是主轴居中,align-item: center是交叉轴居中

方法四:网格布局grid

写法和弹性一模一样

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 500px;
            height: 500px;
            background-color: rgb(28, 101, 164);
            display: grid;
            justify-content: center;
            align-items: center;
        }
        .wrap {
            width: 200px; 
            height: 200px; 
            background-color: green;
        }
    </style>
</head>
<body>
    <div>
        <div>hhhhhh</div>
    </div>
</body>
</html>

方法五:表格布局table,text-align和vertical-aligin

用表格布局就需要用上text-align: center来居中,那么就需要子元素是非块级元素,所以将子元素设置display: inline-block成为行内块,表格元素在y轴上居中用vertical-align: middle;

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 500px;
            height: 500px;
            background-color: rgb(28, 101, 164);
            display: table-cell;
            text-align: center;
            vertical-align: middle;
        }
        .wrap {
            display: inline-block;
            width: 200px;
            height: 200px;
            background-color: green;
        }
    </style>
</head>
<body>
    <div>
        <div>hhhhhh</div>
    </div>
</body>
</html>

文字水平垂直居中text-aligin、line-height

对于文字的水平垂直居中,你可以使用text-align: centerline-height来设置,line-height的参数设置成父容器的高即可

块级元素仅水平居中 margin: 0  auto

margin: 0 auto常见于仅水平居中块级元素,无法垂直居中

十、flex弹性布局怎么理解?

一、什么是Flex弹性布局? Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。

CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。

引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。

弹性盒子由弹性容器(Flex container)和弹性子元素(Flex item)组成。

弹性容器通过设置 display 属性的值为 flex 或 inline-flex将其定义为弹性容器。

弹性容器内包含了一个或多个弹性子元素。

任何一个容器都可以指定为 Flex 布局。

十一、css中的动画属性

1. transition 属性

transition 属性用于定义元素从一种样式逐渐改变为另一种样式时的效果,通常用于过渡效果。

子属性:
  • transition-property:指定哪些 CSS 属性将受到过渡效果的影响。

  • transition-duration:过渡的持续时间。

  • transition-timing-function:过渡的速度曲线。

  • transition-delay:过渡开始之前的延迟时间。

2. transform 属性

transform 属性用于改变元素的位置、尺寸、旋转等,通常配合 transition 使用。

子属性:
  • translate(x, y):将元素沿 x 轴和 y 轴移动。

  • scale(x, y):将元素沿 x 轴和 y 轴缩放。

  • rotate(angle):将元素旋转指定的角度。

  • skew(x-angle, y-angle):将元素倾斜指定的角度。

  • matrix(a, b, c, d, e, f):使用矩阵来定义变换。

3. animation 属性

animation 属性用于定义关键帧动画,可以实现更复杂的动画效果。

子属性:
  • animation-name:指定关键帧的名称。

  • animation-duration:动画的持续时间。

  • animation-timing-function:动画的速度曲线。

  • animation-delay:动画开始之前的延迟时间。

  • animation-iteration-count:动画播放的次数。

  • animation-direction:动画播放的方向。

  • animation-fill-mode:动画开始前或结束后元素的状态。

  • animation-play-state:动画的播放状态(播放或暂停)。

4. will-change 属性

will-change 属性提示浏览器在渲染时优化特定属性的动画效果。

5. backface-visibility 属性

backface-visibility 属性用于控制元素背面是否可见,通常用于3D变换。

6. perspective 属性

perspective 属性定义了3D空间的透视效果。

7. transform-origin 属性

transform-origin 属性用于定义元素变换的中心点。

8. animation-fill-mode 属性

animation-fill-mode 属性定义了动画开始前和结束后元素的状态。

9. animation-direction 属性

animation-direction 属性定义了动画播放的方向。

10. animation-play-state 属性

animation-play-state 属性定义了动画的播放状态(播放或暂停)。

十三、promise

一、什么是Promise

Promise是抽象异步处理对象以及对其进行各种操作的组件。Promise本身是同步的立即执行函数解决异步回调的问题, 当调用 resolve 或 reject 回调函数进行处理的时候, 是异步操作, 会先执行.then/catch等,当主栈完成后,才会去调用执行resolve/reject中存放的方法。promise的功能是可以将复杂的异步处理轻松地进行模式化。采用Promise,连续读取多个文件,可以解决回调地狱。如果说到基于JavaScript的异步处理,我想大多数都会想到利用回调函数。

Promise本身是同步的立即执行函数, 当在executor中执行resolve或者reject的时候, 此时是异步操作, 会先执行then/catch等,当主栈完成后,才会去调用resolve/reject中存放的方法执行。

二、ES6 Promises 的API方法

1、参数:Promise构造函数接受一个函数作为参数,其中该参数又接受两个函数作为它自身的参数,分别是resolve和reject。
new Promise((resolve, reject) => {
    //异步操作
})
 
promise.then(function(data) {
    console.log('success');
}).catch(function(error) {
    console.log('error');
});

1.1  resolve

返回一个promise对象成功的状态,并通知给then方法或catch方法,接下来根据对象的状态决定走哪条路,然后执行后续操作;resolve方法的作用是把promise对象的状态从进行中变成已完成,同时可以向resolve方法传入参数,这个参数会在将来被promise对象的then方法获取;

1.2 reject

返回一个失败的promise对象;reject方法也是同样的道理,只不过是把promise对象状态变成失败,同时传入的参数会被catch方法获取而已;

当resolve或reject修改promise对象状态之后,通过检测promise对象的状态,决定执行then还是catch回调方法。在这个过程中:resolve和reject起到的作用是修改对象状态、通知回调函数以及传递回调函数可能需要的参数。这样做的好处就是:把逻辑判断和回调函数分开处理;

2、回调函数 .then 和 .catch

回调函数的调用是根据对象的状态来完成的:进行中、已完成和失败**(pending(进行中)**、fullfilled(成功)rejected(失败)

2.1 Promise.then
  1. 得到异步任务的正确结果;

  2. 只有Promsie内部的状态落定了,then方法中对应的处理程序才会执行;

  3. then方法的强大之处,可以链式调用;

2.2 Promise.catch

进行捕获和处理失败结果;

3、方法 .all() 和 .race()

3.1  Promise.all()

并发处理多个异步任务(等待机制),所有结果都返回之后,统一打印; 谁跑得慢,以谁为准执行回调; Promise.all 接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then 方法;

3.2 Promise.race()
  1. 并发处理多个异步任务(赛跑机制), 任何一个异步操作完成,就执行下一步的.then;请求图片的时候使用;

  2. 谁跑得快,以谁为准执行回调;

十四、http的请求方式

HTTP 的 八大请求方式:GET、 POST、 HEAD、OPTIONS、 PUT、 DELETE、 TRACE、 CONNECT。

一、GET

GET 动作:用于获取资源,当采用 GET 方式请求指定资源时, 被访问的资源经服务器解析后立即返回响应内容。

通常以 GET 方式请求特定资源时, 请求中不应该包含请求体,所有需要向被请求资源传递的数据都应该通过 URL 向服务器传递。

二、POST

POST 动作:用于提交数据, 当采用 POST 方式向指定位置提交数据时,数据被包含在请求体中,服务器接收到这些数据后可能会建立新的资源、也可能会更新已有的资源。

同时 POST 方式的请求体可以包含非常多的数据,而且格式不限。因此 POST 方式用途较为广泛,几乎所有的提交操作都可以使用 POST 方式来完成。

虽然用 GET 方式也可以提交数据,但一般不用 GET 方式而是用 POST 方式。在 HTTP协议中,建议 GET 方式只用来获取数据,而 POST 方式则用来提交数据(而不是获取数据)。

★ get方式和post方式有何区别

简单来说,本质上区别:

- GET产生 一个 TCP数据包
- POST产生 两个 TCP数据包

也就是说:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

详细区别: 数据携带上:

GET方式:在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。 POST方式:可以在请求的实体内容中向服务器发送数据,传送的数据量无限制。 请求参数的位置上:

GET方式:请求参数放在URL地址后面,以 ? 的方式来进行拼接 POST方式:请求参数放在HTTP请求包中 用途上:

GET方式一般用来获取数据

POST方式一般用来提交数据

首先是因为GET方式携带的数据量比较小,无法带过去很大的数量

POST方式提交的参数后台更加容易解析(使用POST方式提交的中文数据,后台也更加容易解决)

GET方式比POST方式要快 GET方式比POST方式要快

更快的原因:

1.post请求包含更多的请求头 因为post需要在请求的body部分包含数据,所以会多了几个数据描述部分的首部字段(如content-type),这其实是微乎其微的。

2.post在真正接受数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据

post请求的过程:

[1].浏览器请求tcp连接(第一次握手)

[2].服务器答应进行tcp连接(第二次握手)

[3].浏览器确认,并发送post请求头(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)

[4].服务器返回100 continue响应

[5].浏览器开始发送数据

[6].服务器返回200 ok响应

get请求的过程:

[1] .浏览器请求tcp连接(第一次握手)

[2].服务器答应进行tcp连接(第二次握手)

[3].浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)

[4].服务器返回200 ok响应

也就是说,目测get的总耗是post的2/3左右

3、get会将数据缓存起来,而post不会

4、post不能进行管道化传输

所以,在可以使用get请求通信的时候,不要使用post请求,这样用户体验会更好,当然,如果有安全性要求的话,post会更好。

三、PUT

PUT 动作:用于向指定位置提交数据, 当采用 PUT 方式向指定位置提交数据时, 数据被包含在请求体中, 服务器接收到这些数据后直接在当前位置(即提交数据时指定的位置) 创建新的资源。

PUT 方式和 POST 方式极为相似,都可以向服务器提交数据,

PUT 方式通常指定了资源的存放位置(即提交数据时指定的位置)

POST 方式所提交的数据由服务器决定存放位置(可能是新增数据,也可能是更新数据)。

在 HTTP 规范中,建议 PUT 方式只用来创建新的资源。

四、DELETE

DELETE 动作:用于删除特定位置的资源。

采用 DELETE 方式访问特定位置的资源时, 服务器接受到请求后会删除当前位置对应的资源。

五、HEAD

HEAD 动作:用于获取响应头,采用 HEAD 方式请求指定资源时,被访问的资源经服务器解析后立即返回响应,但返回的响应中仅包含状态行和响应头,不包含响应体。

HEAD 动作通常 用于完成测试 URI 的有效性、 获取资源更新时间等操作。

六、TRACE

TRACE 动作:用于回显服务器收到的请求,主要用于测试或诊断。

七、OPTIONS

OPTIONS 动作:用于查询服务器针对特定资源所支持的 HTTP 请求方式,即询问客户端可以以那些方式来请求相应的资源, 同时使用 OPTIONS 方式也可以用来测试服务器的性能。

八、CONNECT

CONNECT 动作:要求在与代理服务器通信时建立隧道, 实现用隧道协议进行 TCP 通信。主要使用 SSL(安全套接层)和 TLS(传输层安全) 协议把通信内容加密后经网络隧道传输。

十五、http常见的状态码

HTTP状态码表示客户端HTTP请求的返回结果、标记服务器端的处理是否正常或者是出现的错误,能够根据返回的状态码判断请求是否得到正确的处理很重要。

1. 信息响应(1xx)

这类状态码表示请求已被接收,需要继续处理。

  • 100 继续(Continue):服务器已经收到了部分请求,但需要客户端继续发送剩余的部分。

  • 101 切换协议(Switching Protocols):服务器将遵照客户端的请求切换协议。

  • 102 处理(Processing):这是一个 WebDAV 请求状态码,表示处理将在异步模式下继续。

  • 103 早期提示(Early Hints):服务器希望客户端继续发送请求,但已经在响应中提前提供了某些提示信息。

2. 成功(2xx)

这类状态码表示请求已成功被服务器接收、理解,并接受了。

  • 200 OK:请求已成功,请求所希望的响应头或数据体将随此响应返回。

  • 201 Created:请求已成功,需要在返回的响应中附带一个新的资源的 URI,如果有新建资源的话。

  • 202 Accepted:服务器已接受请求,但尚未处理。

  • 203 Non-Authoritative Information:请求已成功处理,但返回的信息可能来自另一来源。

  • 204 No Content:服务器成功处理了请求,但没有返回任何内容。

  • 205 Reset Content:服务器成功处理了请求,但没有返回任何内容,并要求客户端重置表单域。

  • 206 Partial Content:服务器成功处理了部分 GET 请求。

  • 207 Multi-Status:多状态响应(多个状态行)。

  • 208 Already Reported:已报告(WebDAV)。

  • 226 IM Used:IM 已使用(WEBDAV)。

3. 重定向(3xx)

这类状态码表示需要客户端采取进一步的操作才能完成请求。

  • 300 Multiple Choices:目标资源有多个位置可供选择,并且位置已在响应的 Location 字段信息中返回;用户代理或用户必须选择一个位置,然后再次发出 GET 请求。

  • 301 Moved Permanently:请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本次响应中给出的 URI。

  • 302 Found:请求的资源现在临时从不同的 URI 响应请求。由于这样的重定位是临时的,因此客户端应当继续使用本次响应中提供的 URI 发送未来的请求。

  • 303 See Other:对应的资源可以通过另一个 URI 被找到,并且应当使用 GET 方法检索此资源。

  • 304 Not Modified:自从上次请求后,请求的资源并未修改过。因此,可以继续使用此缓存版本。

  • 305 Use Proxy:请求的资源必须通过指定的代理才能被访问。

  • 307 Temporary Redirect:请求的资源现在临时从不同的 URI 响应请求。由于这样的重定位是临时的,因此客户端应当继续使用本次响应中提供的 URI 发送未来的请求。

  • 308 Permanent Redirect:请求的资源现在永久从不同的 URI 响应请求。

4. 客户端错误(4xx)

这类状态码表示请求包含语法错误或无法完成。

  • 400 Bad Request:服务器无法理解请求的格式。

  • 401 Unauthorized:请求要求用户的身份认证。

  • 403 Forbidden:服务器理解请求客户端的请求,但是拒绝执行此请求。

  • 404 Not Found:请求的资源不存在。

  • 405 Method Not Allowed:请求的方法不允许对请求的目标资源执行。

  • 406 Not Acceptable:请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。

  • 408 Request Timeout:请求超时。

  • 409 Conflict:请求的资源状态冲突。

  • 410 Gone:请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。

  • 411 Length Required:服务器要求在请求报文中包含表示报文长度的 Content-Length 头部。

  • 412 Precondition Failed:服务器在验证请求头中的条件时失败。

  • 413 Payload Too Large:请求实体太大。

  • 414 URI Too Long:请求的 URI 太长。

  • 415 Unsupported Media Type:请求的格式不受服务器支持。

  • 416 Range Not Satisfiable:请求的范围不符合要求。

  • 417 Expectation Failed:服务器未能满足期望请求。

  • 418 I'm a teapot:一个幽默的状态码,表示设备是茶壶,无法冲泡咖啡。

  • 422 Unprocessable Entity:请求格式正确但无法被完成。

  • 429 Too Many Requests:用户发送了太多请求,在一定时间内被限流。

  • 451 Unavailable For Legal Reasons:因法律原因不可用。

5. 服务器错误(5xx)

这类状态码表示服务器在处理请求的过程中发生了错误。

  • 500 Internal Server Error:服务器遇到了未曾预料的情况,无法完成对请求的处理。

  • 501 Not Implemented:服务器不支持当前请求所需的功能。

  • 502 Bad Gateway:作为网关或代理工作的服务器从上游服务器收到了无效的响应。

  • 503 Service Unavailable:服务器暂时无法使用(由于超载或停机维护)。

  • 504 Gateway Timeout:作为网关或代理工作的服务器从上游服务器等待响应请求的时间太长。

  • 505 HTTP Version Not Supported:服务器不支持请求中所使用的 HTTP 协议版本。

  • 506 Variant Also Negotiates:由透明内容协商协议产生的错误。

  • 507 Insufficient Storage:服务器无法存储完成请求所需的完整内容(WebDAV)。

  • 508 Loop Detected:服务器检测到无限循环重定向(WebDAV)。

  • 510 Not Extended:进一步扩展的工作被永久停止。

  • 511 Network Authentication Required:需要网络认证才能获得请求的响应。

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.