腾讯实习面试总结(一)
项目
vue的插件用过哪些?
vue router和vuex。
Vue Router 是 Vue.js官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
vuex是什么?
vuex是vue.js提供的一个状态管理工具。说了一下之前项目中遇到的多用户登录验证的问题,用的是sessionStorage存储登录的状态,比较了为什么没有用vuex(当页面强制刷新之后vuex状态会被清空,面试官感到了怀疑)。
sessionStorage localStorage和cookie?
localStorage会一直存储状态直到手动删除,这里因为做的是登录的用户验证,所以需要有一个会话时间的限制。
cookie和HTML的storage比起来,存储的数据量更小一点。
项目中印象最深的是什么?
这个回答得不好,没有说得很具体,只说了一些知识点的储备和一些bug的修改。
数据交互,MVC模型和MVVM模型?vue是怎么实现的MVVM?
ExtJs是MVC模型,视图和数据分离,用控制器实现一些基本的操作,但是需要进行事件监听,操作dom结构,性能不高。
Vue.js是MVVM模型,通过在view model层进行数据绑定,数据驱动视图,数据发生改变后视图也发生改变,不需要事件监听和
JS基础
数组的基本操作
- 删除第二个数:splice
- 删除/添加第一个数:shift/unshift
- 删除/添加最后一个数:pop/push
- 数组排序:sort
- 一个可选的参数,作为排序顺序的函数
- 返回一个用于说明这两个值的相对顺序的数字
- 从小到大返回负数(a-b),从大到小返回正数(b-a)
对象的继承
1.原型链
重写子类型的原型对象,代之以一个新类型的实例。
1 | SubType.prototype = new SuperType(); |
- 构造函数、原型、实例的关系:
- 每个构造函数都有一个原型对象;
- 原型对象都包含一个指向构造函数的指针;
- 实例包含一个指向原型对象的内部指针
- 所有引用类型都默认继承了Object,这个继承是通过原型链实现的
- 确定原型和实例之间的关系:instanceof操作符 / isPrototypeOf()方法
- 原型链的问题:
- 引用类型的值会共享,所有的子类型的实例都会共享引用类型的属性,一个实例修改了这个属性,另一个实例也会被修改
- 在创建子类型的实例时,不能向超类型的构造函数中传递参数。
2.借用构造函数(伪造对象或经典继承)
在子类型构造函数的内部调用超类型的构造函数。
1 | function SubType(){ |
- 可以在子类型构造函数中传递参数
- 借用构造函数的问题:方法都在构造函数中定义,无法做到函数复用(不同实例的同名方法是相同的)
3.组合继承
借用构造函数继承属性,原型链继承方法。(最常用的继承模式)
- 组合继承的问题:无论什么情况下,都会调用两次超类型的构造函数。一次是在创建子类型原型的时候,一次是在子类型构造函数的内部。(解决方法:寄生组合式继承)
4.原型式继承
不需要构造函数,基于已有的对象创建新对象
1 | function object(o){ |
ES5新增了Object.create() 规范了原型式继承
- 原型式继承的问题:引用类型属性共享(和原型链类似)
5.寄生式继承
创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再返回对象。
1 | function createAnother(original){ |
- 在主要考虑对象而不是自定义类型和构造函数的情况下,可以使用寄生式继承。
- 寄生式继承的问题:使用寄生式继承为对象添加函数,会由于不能做到函数复用降低效率(和构造函数模式类似)
6.寄生组合式继承
通过借用构造函数继承属性,通过原型链的混成形式继承方法。不必为了指定子类型的原型调用超类型的构造函数。本质上就是使用寄生式继承来继承超类型的原型,再将结果指定给子类型的原型。
1 | function inheritPrototype(subType,superType){ |
闭包
闭包是指有权访问另一个函数作用域中的变量的函数。常见方式是在一个函数内部创建另一个函数。
闭包的用途
- 可以读取函数内部的变量
- 可以让这些变量的值始终保持在内存中
- 在没有class的概念之前,可以使用闭包封装私有变量和私有方法
跨域
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源。
广义的跨域
- 资源跳转:A链接、重定向、表单提交
- 资源嵌入:link、script、img、frame等dom标签,样式中的background:url()、@font-face()等文件外链
- 脚本请求:js发起的ajax请求、dom和js对象的跨域操作
狭义的跨域
浏览器同源策略限制的一类请求场景
同源:协议、域名、端口都相同
同源策略:
- 通常浏览器允许进行跨域写操作(Cross-origin writes),如链接,重定向;
- 通常浏览器允许跨域资源嵌入(Cross-origin embedding),如 img、script 标签;
- 通常浏览器不允许跨域读操作(Cross-origin reads)。*
跨域解决方案
1.jsonp
利用script标签没有跨域的限制,在页面上引入不同域上的js脚本文件是可以的,所以可以通过script标签请求跨域的地址,再出发回调函数处理数据。
- 优点:兼容性好(兼容低版本IE)
- 缺点:1.JSONP只支持GET请求; 2.XMLHttpRequest相对于JSONP有着更好的错误处理机制
2.document.domain+iframe
实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。
该方式只能用于二级域名相同的情况下(主域相同,子域不同),比如 a.test.com 和 b.test.com 适用于该方式。
3.location.hash+iframe
实现原理: a.html 欲与 c.html 跨域相互通信,通过中间页 b.html 来实现。 三个页面,不同域之间利用 iframe 的 location.hash 传值,相同域之间直接 js 访问来通信。
4.window.name+ifame
利用window.name属性。name值在不同域名的页面加载后依然存在,并可以支持较长的name值(2MB)
通过 iframe 的 src 属性由外域转向本地域,跨域数据即由 iframe 的 window.name 从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。
5.postMessage
postMessage 是 HTML5 XMLHttpRequest Level 2 中的 API,且是为数不多可以跨域操作的 window 属性之一。
1 | iframe.contentWindow.postMessage() |
6.CORS跨域资源共享
CORS 是W3C 推荐的一种新的官方方案,能使服务器支持 XMLHttpRequest 的跨域请求。只需要在服务器端设置Access-Control-Allow-Origin就可以开启,该属性表示哪些域名可以访问资源。
目前所有浏览器都支持该功能(IE 8 和 9 需要通过 XDomainRequest 来实现)
值得注意的是,通常使用CORS时,异步请求会被分为简单请求和非简单请求,非简单请求的区别是会先发一次预检请求。
7.nginx代理跨域
实现思路:通过 nginx 配置一个代理服务器(域名与 domain1 相同,端口不同)做跳板机,反向代理访问 domain2 接口,并且可以顺便修改 cookie 中 domain 信息,方便当前域 cookie 写入,实现跨域登录。
8.node.js中间件代理跨域
实现原理:同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。
通过开启一个代理服务器实现数据的转发。代理服务器需要设置CORS首部字段。
非Vue框架需要两次跨域
Vue框架只需要一次跨域
node+webpack+webpack-dev-server代理接口跨域。由于vue渲染服务和接口代理服务都是webpack-dev-server同一个,所以浏览器页面和代理接口之间不再需要跨域了。
9.WebSocket协议跨域
Websocket是HTML5的一种新的协议,实现了浏览器与服务器的全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。
安全
XSS
攻击
反射型
反射型xss一般出现在URL参数中及网站搜索栏中,由于需要点击包含恶意代码的URL才可以触发,并且只能触发一次,所以也被称为“非持久性xss”。
存储型
存储型xss一出现在网站留言板,评论处,个人资料处,等需要用户可以对网站写入数据的地方。比如一个论坛评论处由于对用户输入过滤不严格,导致攻击者在写入一段窃取cookie的恶意JavaScript代码到评论处,这段恶意代码会写入数据库,当其他用户浏览这个写入代码的页面时,网站从数据库中读取恶意代码显示到网页中被浏览器执行,导致用户cookie被窃取,攻击者无需受害者密码即可登录账户。所以也被称作“持久性xss”。持久性xss比反射型xss危害要大的多。
DOM型
DOM xss是基于dom文档对象模型,前端脚本通过dom动态修改页面,由于不与服务端进行交互,而且代码是可见的,从前端获取dom中的数据在本地执行。
常见的可以操纵dom的对象:URL,localtion,referrer等
防御
- 编码:对用户输入的数据进行HTML Entity编码
- 过滤:白名单或黑名单过滤。移除用户上传的DOM属性、script、style、iframe节点
- HttpOnly:对于设置了httponly属性的网页,浏览器将禁止页面的javascript访问cooike。这可以很好的解决产生XSS后的Cookie劫持问题。
- 浏览器过滤:filter/auditor:X-XSS-Protection。就是浏览器内置的一种 XSS 防范措施。是 HTTP 的一个响应头字段,要开启很简单,在服务器的响应报文里加上这个字段即可。浏览器接收到这个字段则会启用对应的 XSS 防范模块。针对反射型XSS
- CSP(内容安全策略):是一个附加的安全层,有助于检测并缓解某些类型的攻击,包括跨站脚本(XSS)和数据注入攻击。通常可以通过HTTP Header中的Content-Security-Policy来开启CSP。
CSRF
攻击
跨站请求伪造,是一种挟持用户在当前已登录的Web应用上执行非本意的操作的攻击方法。
防御
- SameSite:对Cookie设置该属性,设置Cookie不随着跨域请求发送。但不是所有浏览器都兼容。
- 验证Referer:来判断该请求是否为第三方网站发起的
- Token:服务器下发一个随机Token,每次发起请求时携带Token,服务器验证是否有效。