初级前端面试总结
文章目录
一、cookie、sessionStorage和localStorage的区别
答:
1、存储大小
- cookie只能存储 4K的数据,每个域名一般存储量不超过20个。
- localstorage和sessionstorage,存储大小为 5mb
2、有效期
- cookie有效期可以自己自定义,未设置有效期是浏览器关闭后则被删除,设置有效期后则将数据存储到 硬盘中。默认不会存储到硬盘。(同一个浏览器,同一个标签页/不同的标签页 均可共享)
- localstorage一直存储在客户端,除非用户自行删除或者清除缓存,否则一直存在。(同一个浏览器,同一个标签页/不同的标签页 均可共享)
- sessionstorage:存储在客户端,默认关闭浏览器则自行删除。(不同浏览器,同一个标签页 均可以共享)
3、运用场景
- cookie一般用于存储不敏感信息且使用较广(安全性较低,不建议使用)
- sessionstorage:用于存储 一次性数据,关闭浏览器则被丢弃。
- localstorage:一般用于登录验证,存储用户登录信息。
4、安全性、服务端通信
- cookie安全性较低,容易被人攻击,或者串改信息。每次请求不管服务端是否需要,都会携带cookie,从而降低了传输带宽
- sessionstorage:不用参与服务端,一直存储到客户端,接口可以直接使用,安全性较高。
- localstorage:不用参与服务端,一直存储到客户端,接口可以直接使用,安全性较高。
5、作用域
- cookie作用域同一个浏览器,同一个标签页/不同的标签页 均可共享
- localstorage:同一个浏览器,同一个标签页/不同的标签页 均可共享
- sessionstorage:不同浏览器,同一个标签页 均可以共享
6、存储位置
- cookie:一般存储 浏览器客户端
- localstorage:一般存储 浏览器客户端
- sessionstorage:一般存储 浏览器客户端
7、机制不同
- cookie:每次请求接口时,均要携带所有cookie值
- localstorage:不参与接口机制,但是接口可以直接使用
- essionstorage:不用参与服务端,接口可以直接使用
8、参考文献
【1】 https://blog.youkuaiyun.com/weixin_42614080/article/details/90706499
二、HTTP状态码
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型。
分类 | 分类描述 |
---|---|
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
HTTP状态码表(版本1) 此表含状态码英文名称
状态码 | 状态码英文名称 | 中文描述 |
---|---|---|
1开头的状态码 | ||
100 | Continue | 继续。客户端应继续其请求 |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
2开头的状态码 | ||
200 | OK | 请求成功。一般用于GET与POST请求 |
201 | Created | 已创建。成功请求并创建了新的资源 |
202 | Accepted | 已接受。已经接受请求,但未处理完成 |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
3开头的状态码 | ||
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
306 | Unused | 已经被废弃的HTTP状态码 |
307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
4开头的状态码 | ||
400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
401 | Unauthorized | 请求要求用户的身份认证 |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
409 | Conflict | 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突 |
410 | Gone | 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
412 | Precondition Failed | 客户端请求信息的先决条件错误 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
416 | Requested range not satisfiable | 客户端请求的范围无效 |
417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
5开头的状态码 | ||
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 | Bad Gateway | 充当网关或代理的服务器,从远端服务器接收到了一个无效的请求 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
参考文献
【1】 http://tools.jb51.net/table/http_status_code
三、HTTP的请求方式有哪几种
HTTP Request Method共计15种
序号 | 方法 | 描述 |
---|---|---|
1 | get | 请求指定的页面信息,并返回实体主体。 |
2 | head | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | post | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | put | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | delete | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | options | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
9 | PATCH | 实体中包含一个表,表中说明与该URI所表示的原内容的区别。 |
10 | MOVE | 请求服务器将指定的页面移至另一个网络地址。 |
11 | COPY | 请求服务器将指定的页面拷贝至另一个网络地址。 |
12 | LINK | 请求服务器建立链接关系。 |
13 | UNLINK | 断开链接关系。 |
14 | WRAPPED | 允许客户端发送经过封装的请求。 |
15 | Extension-mothed |
注:一般情况下使用较多的为:get,post,put,delete,head请求
参考文献
【1】 http://tools.jb51.net/table/http_status_code
四、get请求和post请求的区别
1、请求头的区别
- get:没有请求头
- post:有请求头
2、请求参数
- get:请求参数会显示在URL地址
- post:请求参数通过 request body传递参数
3、安全性
- get:参数暴露在URL地址中,安全性较低。
- post:请求参数通过 request body传递,安全性比get高。
4、运用场景
- get:一般运用列表查询,发送少量数据时候使用
- post:一般运用修改 增,修、删除等操作。
5、传输大小
- get:在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。
6、其他
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark(标签),而POST不可以。
- GET请求会被浏览器主动cache(缓存),而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
参考文献
【1】https://www.cnblogs.com/logsharing/p/8448446.html
五、什么原因引起跨域的问题,如何解决的
1、产生跨域的原因
浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
所谓的同源指的是 域名,协议,端口均相同
- 非跨域:http://www.123.com/index.html 调用 http://www.123.com/server.php
- 域名不同 跨域:http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
- 子域名不同跨域:http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)
- 端口不同跨域:http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)
- 协议不同:http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)
注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。
2、解决跨域办法
1、jsonp:
使用方式就不赘述了,但是要注意JSONP只支持GET请求,不支持POST请求。
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$.ajax({
url:"http://crossdomain.com/services.php",
dataType:'jsonp',
data:'',
jsonp:'callback',
success:function(result) {
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
},
timeout:3000
});
</script>
2、vue3 中vue.config.js
文件下 配置 proxyTbale
devServer: {
open: true, //是否自动弹出浏览器页面
host: "localhost",
port: '8081',
https: false,
hotOnly: false,
proxy: {
'/api': {
target: 'https://www.v2ex.com/api', //API服务器的地址
changeOrigin: true, //是否跨域
pathRewrite: {
'^/api': ''
}
}
},
}
3、vue2项目 中config 文件下 index.js 配置跨域
六、keep-alive运用场景,可通过什么函数来触发 函数。
keep-alive:当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。一般运用在 tab选项卡切换,每次切换后不需要调用方法后,则可以采用 keep-alive进行存入缓存。
如果在切换页面后,值更改则需要重新调用接口,则可通过activated
和 deactivated
将会在 <keep-alive/>
树内的所有嵌套组件中触发 函数。
官方说明:
注意这个 <keep-alive/>
要求被切换到的组件都有自己的名字,不论是通过组件的 name
选项还是局部/全局注册。
-
Props:
include
- 字符串或正则表达式。只有名称匹配的组件会被缓存。exclude
- 字符串或正则表达式。任何名称匹配的组件都不会被缓存。max
- 数字。最多可以缓存多少组件实例。
-
用法:
<keep-alive/>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和<transition/>
相似,<keep-alive>
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。当组件在
<keep-alive>
内被切换,它的activated
和deactivated
这两个生命周期钩子函数将会被对应执行。在 2.2.0 及其更高版本中,
activated
和deactivated
将会在<keep-alive/>
树内的所有嵌套组件中触发。主要用于保留组件状态或避免重新渲染。
<!-- 基本 --> <keep-alive> <component :is="view"></component> </keep-alive> <!-- 多个条件判断的子组件 --> <keep-alive> <comp-a v-if="a > 1"></comp-a> <comp-b v-else></comp-b> </keep-alive> <!-- 和 `<transition>` 一起使用 --> <transition> <keep-alive> <component :is="view"></component> </keep-alive> </transition>
注意,
是用在其一个直属的子组件被开关的情形。如果你在其中有 `v-for` 则不会工作。如果有上述的多个条件性的子元素,
要求同时只有一个子元素被渲染。 -
include
andexclude
2.1.0 新增
include
和exclude
属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:<!-- 逗号分隔字符串 --> <keep-alive include="a,b"> <component :is="view"></component> </keep-alive> <!-- 正则表达式 (使用 `v-bind`) --> <keep-alive :include="/a|b/"> <component :is="view"></component> </keep-alive> <!-- 数组 (使用 `v-bind`) --> <keep-alive :include="['a', 'b']"> <component :is="view"></component> </keep-alive>
匹配首先检查组件自身的
name
选项,如果name
选项不可用,则匹配它的局部注册名称 (父组件components
选项的键值)。匿名组件不能被匹配。 -
max
2.5.0 新增
最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
<keep-alive :max="10"> <component :is="view"></component> </keep-alive>
<keep-alive>
不会在函数式组件中正常工作,因为它们没有缓存实例。
七、vuex 中的 store 和 $store 的区别
<router-link to="/login">{{ $store.state.userName }}</router-link>
<router-link to="/login">{{ store.state.userName }}</router-link>
<router-link to="/login">{{ this.store.state.userName }}</router-link>
<router-link to="/login">{{ this.$store.state.userName }}</router-link>
$store
是挂载在 Vue 实例上的(即Vue.prototype),而组件也其实是一个Vue实例,在组件中可使用 this
访问原型上的属性,template 拥有组件实例的上下文,可直接通过 {{ $store.state.userName }}
访问,等价于 script 中的 this.$store.state.userName
。
至于 {{ store.state.userName }}
,script 中的 data
需声明过 store
才可访问。
参考文献
【1】 https://blog.youkuaiyun.com/zeroyulong/article/details/83750708
八、父子组件、兄弟组件之间的传值方式
- 父组件可以使用 props 把数据传给子组件。
- 子组件可以使用 $emit 触发父组件的自定义事件。
- 兄弟组件之间的传值:需新建一个中间组件,然后通过 e m i t ( ) 来 传 递 参 数 ( 类 似 与 子 组 件 给 父 组 件 之 间 的 传 值 方 式 ) , 然 后 通 过 emit()来传递参数(类似与子组件给父组件之间的传值方式),然后通过 emit()来传递参数(类似与子组件给父组件之间的传值方式),然后通过on(functionName, callback)监听 兄弟组件 暴露出来的事件,通过回调函数获取兄弟组件传递出来的值
1、父组件给子组件传值,关键字:props
父组件:
<template>
<div>
<h1>父组件</h1> <!-- 引入子组件 -->
<child :sendMsg="fatherMsg"></child>
</div>
</template>
<script>
import child from '@/components/child'
export default {
name: 'father',
components: {
child
},
data() {
return {
fatherMsg: '嗨,儿子' // 传递给子组件的值
}
}
}
</script>
子组件:通过props拿到父组件传递过来的值
<template>
<div>
<h1>子组件</h1>
<span>获取父组件传值:{{sendMsg}}</span>
</div>
</template>
<script>
export default {
name: 'child',
data() {
return {
}
},
props: ['sendMsg'] // 拿到父组件绑定到sendMsg的值,然后在子组件下显示出来
}
</script>
2、子组件给父组件传值:通过触发事件传递值
子组件:
<template>
<div>
<h1>子组件</h1>
<span>获取父组件传值:{{sendMsg}}</span><hr>
<button @click="sendToFather">子组件给父组件传值</button>
</div>
</template>
<script>
export default {
name: 'child',
data() {
return {
childMsg: '这是来自子组件的数据'
}
},
props: ['sendMsg'],
methods: {
sendToFather: function() {
this.$emit('getChildValue', this.childMsg); // 参数1 getChildValue作为中间状态,参数2 this.childMsg即为传递给父组件的数据
}
}
}
</script>
父组件:
<template>
<div>
<h1>父组件</h1>
<!-- 引入子组件 定义一个on的方法监听子组件的状态,然后通过getChild方法获取子组件传递的数据-->
<child :sendMsg="fatherMsg" v-on:getChildValue="getChild"></child>
<span>这是来自子组件的数据:{{childValue}}</span>
</div>
</template>
<script>
import child from '@/components/child'
export default {
name: 'father',
components: {
child
},
data() {
return {
fatherMsg: '嗨,儿子',
childValue: ''
}
},
methods: {
getChild: function(data) { // 此时的参数data为子组件传递的值,即this.$emit()的第二个参数
this.childValue = data;
}
}
}
</script>
3、同级组件传递数据(兄弟组件)
对于同级组件传值用的较多的情况,推荐直接使用vuex进行状态管理会比较方便。
其原理是先建立一个中间事件 center.js,放在tools文件夹下,如下:
import Vue from 'vue'
export default new Vue()
center.js中我们只创建了一个新的Vue实例,以后它就承担起了组件之间通信的桥梁了,也就是中央事件总线
然后创建第一个子组件first.vue:
<template>
<div class="first-vue-box">
<p>this is firstChild vue</p>
<button @click="sendMsg">发送</button>
</div>
</template>
<script>
import bridge from '../tools/center'
export default {
data () {
return {}
},
methods: {
sendMsg () {
bridge.$emit('firstChildMsg', 'this is firstChild Msg')
}
}
}
</script>
<style lang="scss" scoped>
.first-vue-box {
border: 1px solid blue;
}
</style>
这里先引入事件总线,通过事件总线点击按钮后将first.vue的信息通过事件firstChildMsg的形式发布出去了(我个人的理解是相当于通过事件总线,将first.vue的firstChildMsg这个事件暴露出去),用法跟子组件向父组件传参的模式一样
然后再创建第二个组件second.vue:
<template>
<div class="second-child">
<h4>this is second child vue</h4>
<p>从first.vue获取同级组件传递过来的信息:{{message}}</p>
</div>
</template>
<script>
import bridge from '../tools/center'
export default {
data () {
return {
message: '默认值'
}
},
mounted () {
let _this = this
bridge.$on('firstChildMsg', function (msg) {
_this.message = msg
})
}
}
</script>
在second.vue中再引入事件总线,然后通过$on(functionName, callback)监听first.vue暴露出来的firstChildMsg事件,通过回调函数获取first.vue传递出来的值
引入两个子组件:
<template>
<div class="detail-div">
<h3>首页详情</h3>
<first-child></first-child>
<second-child></second-child>
</div>
</template>
<script>
import firstChild from './first'
import secondChild from './second'
export default {
data () {
return {}
},
components: {
firstChild,
secondChild
},
mounted () {
// console.log('详情页面...')
}
}
</script>
参考文献
【1】:https://www.cnblogs.com/secretAngel/p/9705809.html
九、js 中 == 与 === 的区别?
- == 表示相等 (值相等)
- ===表示恒等(类型和值都要相等)
js在比较的时候如果是 == 会先做类型转换,再判断值得大小,如果是===类型和值必须都相等。
十、webpack打包过程
十一、 1+undefined = ?,1+null = ?
啥都不说,直接贴代码,来的实际
<script>
let a = 1;
let a1 = "1";
let a2 = [1];
let a3 = {a: 1};
let b = undefined;
let c = null;
console.log("----------以下的 1 是number类型:-------------")
console.log( a + undefined)
console.log( a + null)
console.log( a + b)
console.log( a + c)
console.log("----------以下的 1 是字符串类型:-------------")
console.log( a1 + undefined)
console.log( a1 + null)
console.log( a1 + b)
console.log( a1 + c)
console.log("----------以下的 1 是数组类型:-------------")
console.log( a2 + undefined)
console.log( a2 + null)
console.log( a2 + b)
console.log( a2 + c)
console.log("----------以下的 1 是object类型:-------------")
console.log( a3 + undefined)
console.log( a3 + null)
console.log( a3 + b)
console.log( a3 + c)
</script>
结果集:
十二、es6中模板字符串一共有几种用法,分别是?
推荐一本es6语法极好电子书籍 阮一峰 - ECMAScript 6 入门