前端面试题五
1. TCP和UDP的区别
(1)TCP面向连接的;UDP是面向无连接的。
(2)TCP提供可靠的数据传输服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达。UDP尽最大努力交付,即保证不可靠交付。
(3)TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流。
UDP是面向报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率变低(对实时应用很有用,如IP电话,实时视频会议等)
(4)每一条TCP连接只能是点到点的。
UDP支持一对一,一对多,多对一和多对多的交互通信。
(5)TCP首部开销20字节。
UDP的首部开销小,只有8个字节。
(6)TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。
2. TCP, HTTP、IP分别在哪一层
TCP:传输层
HTTP:应用层
IP:网络层
3. Vue是怎样编译的
4. 手写防抖
function debounce(f,wait){ let timer return(..args)=>{ clearTimeout(timer) timer=setTimeout(()=>{ f(...args ) },wait) } }
思想:采用分治的思想,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的数据比另一部分的数据都要小,然后再按此方法对这两部分分别进行排序,整个排序过程可以递归进行。
6. 常用的数据结构
数组、栈、队列、链表、树、散列表、堆、图
7. 手写Set类,包含add和remove方法
8. 网络的五层模型和七层模型
9. 同源策略,什么地方用到了同源策略
同源策略简单来说就是JavaScript代码能够操作哪些web内容的一条完整的安全限制。也是由Netscape提出的一个著名的安全策略。
而同源则是域名、端口、协议三者相同。
浏览器用到了同源策略。
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
10. src和href有哪些区别
(1)请求资源类型不同
href是Hyper Reference的缩写,表示超文本引用。用来建立元素和文档之间的连接。常用的a,link。
src是Soure,在请求资源时,会把其指向的资源下载并应用到文档中,常用的有script、img、iframe
(2)作用结果不同
href用于在当前文档和引用资源之间确立联系。
src用于替换当前内容。
(3)浏览器的解析方式不同
若在文档中添加href,浏览器会识别这个文档并命名为css文件,就会并行下载资源,不会停止对当前文档的处理。这也是为什么建议使用link加载css,而不是使用@import方式。
当浏览器解析到src,会暂停对其他资源的下载和处理,直到将该资源加载、编译和执行完毕。图片和框架等也如此,类似于将所指向资源应用到当前内容。这也是为什么建议把 js 脚本放在底部而不是头部的原因。
11. link和@import的区别
(1)link是XHTML标签,除了能够加载CSS,还可以定义RSS等其他事务;而@import属于CSS范畴,只可以加载CSS。
(2)link引用CSS时,在页面载入时同时加载;@import需要页面完全载入以后再加载。
(3)link是XHTML标签,无兼容问题;@import则是在CSS2.1提出的,低版本的浏览器不支持。
(4)link支持使用Javascript控制DOM改变样式;而@import不支持。
12. ajax请求中readyState都有哪些,代表什么
readyState 属性表示Ajax请求的当前状态。它的值用数字代表。
0 代表未初始化。 还没有调用 open 方法
1 代表正在加载。 open 方法已被调用,但 send 方法还没有被调用
2 代表已加载完毕。send 已被调用。请求已经开始
3 代表交互中。服务器正在发送响应
4 代表完成。响应发送完毕
5 个状态,分别是 0-4
0: 还没调用open方法
1: 未调用send方法,也就是还没发送数据给服务器
2: 还没有接收到响应
3: 开始接收到了部分数据
4: 接收完成,数据可以在客户端使用了
常用状态码(status)及其含义:
404 没找到页面(not found)
403 禁止访问(forbidden)
500 内部服务器出错(internal service error)
200 一切正常(ok)
304 没有被修改(not modified)(服务器返回304状态,表示源文件没有被修改 )
13. 前端安全
(1)xss跨站脚本攻击
原理:页面渲染的数据中包含可运行的脚本
攻击的基本类型:反射型(url参数直接注入)和存储型(存储到DB后读取时注入)
注入点:HTML节点内的内容(text);HTML中DOM元素的属性;Javascript代码;富文本
//HTML节点内容注入 <div><script>alert(1);</script></div> //DOM属性注入 <img src='/images/1.png' onerror='alert(1);'> //javascript代码 <script> var a = '1';alert(1);'' </script> //富文本是html标签,文字,以及样式的集合,很容易实现HTML节点内容注入和DOM属性注入,有被攻击的风险
(2)csrf跨站请求伪造攻击
原理:在第三方网站向本网站发起请求(如图)
(3)点击劫持
原理:第三方网站通过iframe内嵌某一个网站,并且将iframe设置为透明不可见,将其覆盖在其他经过伪装的DOM上,伪装的可点击DOM(按钮等)与实际内嵌网站的可点击DOM位置相同,当用户点击伪装的DOM时,实际上点击的是iframe中内嵌的网页的DOM从而触发请求操作
特点:用户自己做了点击操作;用户毫不知情;
如何防御:(1)xss攻击防御
1)浏览器自带防御机制,主要应对反射型攻击(HTML内容或属性):http响应头中自动添加x-xss-protection,值为0(关闭),1(打开),默认打开
2)对特定字符做转义:内容注入替换尖括号( < => < > => > ) 属性注入替换单引号或双引号( " => " ' => ' )
3)CSP(Content Security Policy)内容安全策略:用于指定哪些内容可执行
//我们可以在http响应头中设置Content-Security-Policy //图片可以从任何地方加载(注意 "*" 通配符) //多媒体文件仅允许从 media1.com 和 media2.com 加载(不允许从这些站点的子域名) //可运行脚本仅允许来自于userscripts.example.com Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com //同时meta中也支持设置Content-Security-Policy <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
(2)csrf防御
1)禁止第三方网站携带本网站的cookie信息:设置same-site属性,same-site属性有两个值,Strict(所有的第三方请求都不能携带本网站的cookie)和Lax(链接可以,但是form表单提交和ajax请求不行)
2)本网站前端页面添加验证信息:使用验证码或者添加token验证
验证码:当发起请求时,前端需要输入本网站页面的验证码信息,后端对验证码进行验证,验证码正确才会进行相关操作(存取数据等)
token验证:a站前端将token存在当前页面中(比如表单中的input隐藏域,meta标签或者任何一个dom的属性)和cookie中,当请求a站后端的时候,参数中带上这个token字段,a站后端将参数中的token和cookie中的token做对比, 相同则验证通过,不同则请求不合法
不管是验证码还是token验证,原理都是一样的,在a站前端页面加入验证,当第三方网站请求a站后端时,即使能携带a站cookie,但是因为没有经过a站的前端页面从而拿不到验证信息,也会导致请求失败。
两种防御的方法也有区别,验证码需要用户去填写,从而增加了用户使用网站的复杂度,而token验证在用户无感知的情况下就可以实现,不影响用户体验。我个人理解,验证码验证一般使用在需要提高用户认知的场景,比如,登录多次失败,修改个人信息(用户名,密码,绑定手机号等等),而一些获取商品列表信息,搜索等接口,使用token比较合理。可以看看我们平时使用的这些网站,作参考~
3)referer验证:禁止来自第三方的请求
4)使用post请求:有一个说法是“post请求比get请求更安全”,那这种说法对不对呢?实际上这种说法并不准确,对于CSRF攻击来讲,不管是post还是get都能实现攻击,区别只是post请求攻击方需要构造一个form表单才可以发起请求,比get请求(img的src, a标签的href等等)的攻击方式复杂了一些,但是并不能有效的阻止攻击。
(3)点击劫持攻击防御
1)Javascript禁止内嵌:当网页没有被使用iframe内嵌时,top和window是相等的;当网页被内嵌时,top和window是不相等的;可以在本网站的页面中添加如下判断:
<script> if (top.location != window.location) { //如果不相等,说明使用了iframe,可进行相关的操作 } </script>
但是这种方式并不是万能的,因为iframe标签中的属性sandbox属性是可以禁用内嵌网页的脚本的:
<iframe sandbox='allow-forms' src='...'></iframe>
2)设置http响应头 X-Frame-Options:有三个值 DENY(禁止内嵌) SAMEORIGIN(只允许同域名页面内嵌) ALLOW-FROM(指定可以内嵌的地址)
能在所有的web服务器端预设好X-Frame-Options字段值是最理想的状态。
3)一些辅助手段,比如添加验证码,提高用户的防范意识
14. 在调用接口的页面中,刚进来时产生白屏可能是什么原因?
(1)首页直出时间过长
(2)依赖js没加载完全
(3)文件依赖关系表map.js加载不正确
(4)接口调用时间过长
解决方案:
(1) 如果是基于 Cake[3] 工具开发的,也可以直接用首屏填充伪标签。
(2) 尽量同步输出,异步输出请尽量 mock 出现在首屏的模板。
(3) 需要使用nodejs直出了,通过在服务端增加一个nodejs中间层,由nginx将前端的请求转发到nodejs上,nodejs响应请求,加载资源,向底层的cgi进行API请求,之后进行拼接,返回html页面,这样资源跟api的请求时间都在服务端完成,缩短了时间,至于模板之类的,还是能够用到前端。当然nodejs也会有请求资源错误的情况,这个时候就需要返回错误标志给前端,前端再发起原来的异步请求,这种方式相当于一种容灾保障。
(4)因为是应用方式,所以总是难免存在一些基础依赖,比如modjs,backbone, underscore, jquery等,这种一般都会通过打包成一个js来减少http请求以及文件大小。针对这种情况,只能通过打包模式,加载资源的模式进行改进。强烈按照“首页必须”进行开发,按需加载,其他的资源可以放在二屏,毕竟首页决定着是否还会继续使用。
(5) 尽量减少文件夹的嵌套,文件名不要过长
接口调用时间过长也会导致单页面应用的加载时间过长,这种我们主要是前端需要给接口设置timeout
(6)可订制的客户端,也可以仿照(manifest/appcache,不完善不适合)做一个缓存机制,即是判断服务器版本是否与客户端保存的资源一致,不一致即下载新的,一致即直接使用本地的,这样就变成一个类本地应用了。
15. vue组件间通信方式
(1)v-bind props
(2)emit v-on
(3)$children $parent
(4)project inject
(5)eventBus
(6)vuex