1.盒子模型
分为普通盒子模型和怪异盒子模型,区别在于定义盒子的宽高的不同
普通盒子模型:box-sizing:content-box
标签的实际宽度 = 设置的宽度+border+padding
怪异盒子模型:box-sizing:border-box
标签的实际宽度 = 设置的宽度,如果设置了border和padding则需要减掉
2.设置元素水平垂直居中
第一种定位:
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%)
第二种定位:
position:absolute;
margin:auto;
left:0;
top:0;
bottom:0;
right:0;
第三种flex布局:
display:flex;
justfy-content:center;
align-items:center;
3.说一些es6语法
let和const,let表示变量,const表示常量,两者都是块级作用
模板字符串:``表示 let template = `<div><span>hello world</span></div>`
箭头函数:注意没有this指向,继承当前上下文的this关键字
对象初始化的简写,键值对一致时可以只写一个
解构语法 const {name ,age } = {name:'zs',age:16}
...语法,扩展运算符:color=[a,b],fullcolor = [...color,c,d] => [a,b,c,d]
import和export语法,看node版本是否支持,不支持的话去presets设置项设置es2015,
帮你转换成支持的语法,npm i bable-preset-es2015
4.简要说说promise以及里面的一些方法
在promise内部进行错误处理
var promise=new Promise(function(resolve,reject){
try {
throw new Error('test');
}catch(e){
reject(e)
}
})
处理多个请求可以用promise.all方法,将几个请求一起发出,然后将返回的数据由数组
返回,然后去拿自己想要的数据即可
async和await也可以用于异步请求,这么写更加简洁
const makeRequest = async () => {
try {
// this parse may fail
const data = JSON.parse(await getJSON())
console.log(data)
} catch (err) {
console.log(err)
}
}
5.重绘和重排,防抖和节流
例如一些字体颜色背景夜色发生更改会导致重绘,如一些字体大小或者元素大小发生改变
会导致重排,重绘不一定会引起重排但是重排一定会引起重绘
客户在短时间内连续触发同一事件即可使用防抖,即在某个时间期限内指定该函数只能执
行一次,而节流则是在如果短时间内大量触发同一事件,那么在函数执行一次之后,在指
定时间内不再执行,直到过了指定的时间段,即事件以一个时间段为间隔的去执行。
6.输入url之后的流程
用户输入网址,浏览器发起DNS查询请求
建立TPC连接
浏览器向web服务器发送一个http请求
发送相应数据给客户端
浏览器解析http response,渲染页面
7.请简要说说mvc和mvvm的区别
m为model,用于数据处理,v为view,用于视图处理,但是两者不会互相干扰,即数据处理不会去写视图更新相关的操作,而视图更新
中也不会写数据处理相关的操作,此时的mvc中提供了一个c即控制器,c可以直接引用m和v,但是m和v不能直接引用c,c的责任为及
时把m的最新数据赋值给v完成视图的更新。但是随着发展,应用的逻辑越来越复杂,而m和v的定义早就定义死,数据解析这一块全都由
c来完成,但是会导致c越来越臃肿,设计c的当初其实并没有数据解析这一功能,所以我们额外创建了一个专门用来数据解析的一个新
的类,即vm,viewModel。在mvvm里面不是没有c,而是c的存在感被vm模块给大大降低了。之前需要由c处理的东西现在基本都是交给了
vm模块来完成,所以导致c的存在感降低,并不是没有c模块。
vue就是一个mvvm框架,其双向数据绑定原理是利用了object.defineProperty()方法来重新定义了对象获取属性值和设置属性值的的操
作来实现的,也就是其中的get和set方法
8.前端攻击有哪些,原理是什么,有什么解决办法
①.xss跨站脚本攻击
原理:页面渲染的数据中包含可运行的脚本
攻击的基本类型:反射型(url参数直接注入)和存储型(存储到DB后读取时注入)
注入点:HTML节点内的内容(text) html的DOM元素的属性 js代码 富文本
②.CSRF 跨站请求伪造
原理:在第三方网站向本网站发起请求
(1)用户在a站前端页面发起登录(身份认证)请求
(2)a站后端确认身份,登录成功,cookie中存在用户的身份认证信息
(3)b站前端页面向a站后端发起请求,带着a站的cookie信息(身份认证信息),请求成功
综上,可以清楚的知道,只要用户访问了b站的前端页面,b站就可以在用户完全不知道的情况下,带着a站的用户登录信息向a发起请求
③.点击劫持
原理:第三方网站通过iframe内嵌某一个网站,并且将iframe设置为透明不可见,将其覆盖在其他经过伪装的dom上,违章的可点击的
dom与实际的内嵌网站的可点击dom位置相同,当用户点击伪装的dom时,实际上点击的是iframe中内嵌的网页的dom从而触发请求操作
特点:用户自己做了点击事件,但是用户毫不知情
如何防御
①.xss攻击防御
(1)浏览器自带防御机制,主要应对反射型攻击,http响应头中自动添加x-xss-protection,值为0关闭,1打开,默认打开
(2)对特定字符做转义:内容注入替换尖括号,属性注入替换单引号或者双引号
(3)csp内容安全策略:用于指定哪些内容可执行
②.CSRF攻击防御
CSRF有几个特点,b站发送的请求携带a站的cookie,b站发送的请求不经过a站前端,http请求头中的referer为b站
(1)禁止第三方网站携带本网站的cookie信息,设置same-site属性,strict值为所有第三方请求都不能携带本网站的cookie,lax值
为链接可以但是form表单提交和ajax请求不行
(2)本网站前端页面添加验证信息:使用验证码或者添加token验证
验证码:当发起请求时,前端需要输入本网站页面的验证信息,后端对验证码进行验证,验证码正确才会进行相关操作(存储数据等)
token验证:a站前端将token存于当前页面和cookie中,当请求a站后端的时候,参数中带上这个token字段,a站后端将参数中的token和
cookie中的token做对比,相同则验证通过,不同则请求不合法
不管是token还是验证码原理都是一样的,在a站前端页面加入验证,当第三方网站请求a站后端时,及时能携带a站的cookie,但是因为
没有经过a站的前端页面而拿不到验证消息,也会导致请求失败
(3)referer验证:禁止来自第三方的请求
③.点击劫持攻击防御
(1)js禁止内嵌:当王爷没有被使用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)一些辅助手段,比如添加验证码,提高用户的防范意识
9.vue中的两种路由模式,并简单说明一下
vue的路由模式有两种,一种hash模式,另外一种为history模式,hash模式可以利用onhashchange事件,可以在windows对象上监听这
个事件,因为hash发生变化的url都会被浏览器记录下来,从而发现浏览器的前进后退都可以用,但是你只能改变#号后面的url片段,在
vue项目中我们用hash模式,使用一个完整的url的hash来模拟一个完整的url,于是当url发生更改的时候,页面不会重新加载,而当页
面使用history模式的时候,在开发阶段可能一切正常,但是项目上线之后,页面发生跳转会给你返回404,因为后端没有配置对应的
url的请求资源,返回的都是同一个index.html页面。
10.深拷贝与浅拷贝
浅拷贝与深拷贝的区别简单来说B是拷贝于A,B改变了A是否跟着改变,如果改变了则是浅拷贝,如果不变则是深拷贝,实现方法如下
浅拷贝的实现方法:
(1)for..in只循环第一层,然后直接赋值
(2)object.assign()方法
var obj = {
a: 1,
b: 2
}
var obj1 = Object.assign(obj);
obj1.a = 3;
console.log(obj.a) // 3
(3)直接=号赋值
深拷贝的实现方法:
(1)采用递归去拷贝所有层级的属性
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
let a=[1,2,3,4],
b=deepClone(a);
a[0]=2;
console.log(a,b);
(2)通过JSON对象来实现深拷贝
function deepClone2(obj) {
var _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone;
}
缺点是无法实现对对象中方法的深拷贝,会显示为undefined
(3)通过jquery的extend()方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝
(4)lodash函数库实现深拷贝 let result = _.cloneDeep(test)使用该方法即可
(5)手动实现深拷贝
let obj1 = {
a: 1,
b: 2
}
let obj2 = {
a: obj1.a,
b: obj1.b
}
obj2.a = 3;
alert(obj1.a); // 1
alert(obj2.a); // 3
(6)如果对象的value是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象
var obj = {
a: 1,
b: 2
}
var obj1 = Object.assign({}, obj); // obj赋值给一个空{}
obj1.a = 3;
console.log(obj.a);// 1
(7)用slice实现对数组的深拷贝
// 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
// 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
var arr1 = ["1","2","3"];
var arr2 = arr1.slice(0);
arr2[1] = "9";
console.log("数组的原始值:" + arr1 );
console.log("数组的新值:" + arr2 );
(8)用concat实现对数组的深拷贝
// 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
var arr1 = ["1","2","3"];
var arr2 = arr1.concat();
arr2[1] = "9";
console.log("数组的原始值:" + arr1 );
console.log("数组的新值:" + arr2 );
// 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
var arr1 = [{a:1},{b:2},{c:3}];
var arr2 = arr1.concat();
arr2[0].a = "9";
console.log("数组的原始值:" + arr1[0].a ); // 数组的原始值:9
console.log("数组的新值:" + arr2[0].a ); // 数组的新值:9
(9)直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
} else {
obj[i] = prop;
}
}
return obj;
}
(10)使用扩展运算符实现深拷贝
// 当value是基本数据类型,比如String,Number,Boolean时,是可以使用拓展运算符进行深拷贝的
// 当value是引用类型的值,比如Object,Array,引用类型进行深拷贝也只是拷贝了引用地址,所以属于浅拷贝
var car = {brand: "BMW", price: "380000", length: "5米"}
var car1 = { ...car, price: "500000" }
console.log(car1); // { brand: "BMW", price: "500000", length: "5米" }
console.log(car); // { brand: "BMW", price: "380000", length: "5米" }
11.vue中的/deep/的作用
vue中的css样式不起作用,用!important也不起作用,此时可以用/deep/,加了之后有作用,此时这个deep是深度作用域。
在vue组建中给style标签添加属性scoped属性可以避免组件内样式对外界造成污染,scoped使得组件内的样式编程局域样式,只作用于
当前组件,如果我们在当前组件内使用了scoped,但是我想在当前组件内改变组件的样式的时候会发现不好使,不好使的原因是因为父
组件内解析的是父组件的hash值,而子组件内标签上添加的是子组件的hash值,对应不上所以没有效果。添加的scoped属性会在标签上
添加一个data-v-hash属性,如果父子组件都有scoped那么子组件最外层既有父组件的hash值又有子组件的hash值。
如何解决不生效,此时需要用到deep,我们可以不加scoped属性,来覆盖子组件的样式
例如.father-div /deep/ .child-div{color:red;}
12.http和https的区别
http:超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,长基于tcp/ip协议传输数据,互联网上应用最为广泛的一
种网络协议,所有的www文件都必须遵守这个标准,设计http的初衷是为了提供一种发布和接收HTML页面的方法。
https:HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用
的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。
TLS是传输层加密协议,前身是SSL协议,由网景公司1995年发布,有时候两者不区分。
SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层与应用层之间对网络连接进行加密。