2019年的春节来的似乎格外的早,过完年相信很多童鞋都开始蠢蠢欲动了;笔者总结了多篇教程,结合平时自己的面试经历,整理了这份文档,希望帮助大家来突击一下前端知识的盲区。文章很长很长很长。。。。(建议先收藏,技术大佬请Ctrl+F4,面向基础
)
整理不易,希望大家关注公众号【前端壹读】
,更多前端原创好文等着你。
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距margin,边框border,填充padding,和实际内容content。盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。
box-sizing: content-box
(W3C盒模型,又名标准盒模型):元素的宽高大小表现为内容的大小。 box-sizing: border-box
(IE盒模型,又名怪异盒模型):元素的宽高表现为内容 + 内边距 + 边框的大小。背景会延伸到边框的外沿。
transition和animation的区别:
Animation和transition大部分属性是相同的,他们都是随时间改变元素的属性值,他们的主要区别是transition需要触发一个事件才能改变属性,而animation不需要触发任何事件的情况下才会随时间改变属性值,并且transition为2帧,从from .... to,而animation可以一帧一帧的。
BFC(Block Formatting Context)格式化上下文,是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。
.parent { text-align: center; } 复制代码
.son { margin: 0 auto; } 复制代码
.parent { display: flex; justify-content: center; } 复制代码
.son { position: absolute; width: 宽度; left: 50%; margin-left: -0.5*宽度 } 复制代码
.son { position: absolute; left: 50%; transform: translate(-50%, 0); } 复制代码
.son { position: absolute; width: 宽度; left: 0; right: 0; margin: 0 auto; } 复制代码
.parent { height: 高度; } .son { line-height: 高度; } 复制代码
.parent { display: table; } .son { display: table-cell; vertical-align: middle; } 复制代码
.parent { display: flex; align-items: center; } 复制代码
.son { position: absolute; top: 50%; height: 高度; margin-top: -0.5高度; } 复制代码
.son { position: absolute; top: 50%; transform: translate( 0, -50%); } 复制代码
.son { position: absolute; height: 高度; top: 0; bottom: 0; margin: auto 0; } 复制代码
absolute
绝对定位 相对于最近的已定位的祖先元素, 有已定位(指position不是static的元素)祖先元素, 以最近的祖先元素为参考标准。如果无已定位祖先元素, 以body元素为偏移参照基准, 完全脱离了标准文档流。
fixed
固定定位的元素会相对于视窗来定位,这意味着即便页面滚动,它还是会停留在相同的位置。一个固定定位元素不会保留它原本在页面应有的空隙。
共同点:改变行内元素的呈现方式,都脱离了文档流;不同点:absolute的”根元素“是可以设置的,fixed的“根元素”固定为浏览器窗口
采用 Flex 布局的元素,称为 Flex 容器
(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目
(flex item),简称“项目”。
属性名 | 属性值 | 备注 |
---|---|---|
display | flex | 定义了一个flex容器,它的直接子元素会接受这个flex环境 |
flex-direction | row,row-reverse,column,column-reverse | 决定主轴的方向 |
flex-wrap | nowrap,wrap,wrap-reverse | 如果一条轴线排不下,如何换行 |
flex-flow | [flex-direction] , [flex-wrap] | 是flex-direction 属性和flex-wrap 属性的简写形式,默认值为row nowrap |
justify-content | flex-start,flex-end,center,space-between,space-around | 设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式 |
align-items | flex-start,flex-end,center,baseline,stretch | 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式 |
属性名 | 属性值 | 备注 |
---|---|---|
order | [int] | 默认情况下flex order会按照书写顺训呈现,可以通过order属性改变,数值小的在前面,还可以是负数。 |
flex-grow | [number] | 设置或检索弹性盒的扩展比率,根据弹性盒子元素所设置的扩展因子作为比率来分配剩余空间 |
flex-shrink | [number] | 设置或检索弹性盒的收缩比率,根据弹性盒子元素所设置的收缩因子作为比率来收缩空间 |
flex-basis | [length], auto | 设置或检索弹性盒伸缩基准值 |
align-self | auto,flex-start,flex-end,center,baseline,stretch | 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式,可以覆盖父容器align-items的设置 |
visibility:hidden、display:none、z-index=-1、opacity:0
clear:both
的空 div 元素,<div class="container"> <div class="left"></div> <div class="right"></div> <div style="clear:both"></div> </div> 复制代码
overflow:hidden
或者 auto 样式,触发BFC。<div class="container"> <div class="left"></div> <div class="right"></div> </div> 复制代码
.container{ width: 300px; background-color: #aaa; overflow:hidden; zoom:1; /*IE6*/ } 复制代码
<div class="container clearfix"> <div class="left"></div> <div class="right"></div> </div> 复制代码
.clearfix{ zoom: 1; /*IE6*/ } .clearfix:after{ content: "."; height: 0; clear: both; display: block; visibility: hidden; } 复制代码
推荐使用第三种方法,不会在页面新增div,文档结构更加清晰。
calc函数是css3新增的功能,可以使用calc()计算border、margin、pading、font-size和width等属性设置动态值。
#div1 { position: absolute; left: 50px; width: calc( 100% / (100px * 2) ); //兼容写法 width: -moz-calc( 100% / (100px * 2) ); width: -webkit-calc( 100% / (100px * 2) ); border: 1px solid black; } 复制代码
注意点:
rem官方定义『The font size of the root element』,即根元素的字体大小。rem是一个相对的CSS单位,1rem等于html元素上font-size的大小。所以,我们只要设置html上font-size的大小,就可以改变1rem所代表的大小。
(function () { var html = document.documentElement; function onWindowResize() { html.style.fontSize = html.getBoundingClientRect().width / 20 + 'px'; } window.addEventListener('resize', onWindowResize); onWindowResize(); })(); 复制代码
一般来说,在PC端浏览器中,设备像素比(dpr)等于1,1个css像素就代表1个物理像素;但是在retina屏幕中,dpr普遍是2或3,1个css像素不再等于1个物理像素,因此比实际设计稿看起来粗不少。
<style> .box{ width: 100%; height: 1px; margin: 20px 0; position: relative; } .box::after{ content: ''; position: absolute; bottom: 0; width: 100%; height: 1px; transform: scaleY(0.5); transform-origin: 0 0; background: red; } </style> <div class="box"></div> 复制代码
div{ border-width: 1px 0px; -webkit-border-image: url(border.png) 2 0 stretch; border-image: url(border.png) 2 0 stretch; } 复制代码
圣杯布局和双飞翼布局是前端工程师需要日常掌握的重要布局方式。两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局。
<style> body{ min-width: 550px; } #container{ padding-left: 200px; padding-right: 150px; } #container .column{ float: left; } #center{ width: 100%; } #left{ width: 200px; margin-left: -100%; position: relative; right: 200px; } #right{ width: 150px; margin-right: -150px; } </style> <div id="container"> <div id="center" class="column">center</div> <div id="left" class="column">left</div> <div id="right" class="column">right</div> </div> 复制代码
<style> body { min-width: 500px; } #container { width: 100%; } .column { float: left; } #center { margin-left: 200px; margin-right: 150px; } #left { width: 200px; margin-left: -100%; } #right { width: 150px; margin-left: -150px; } </style> <div id="container" class="column"> <div id="center">center</div> </div> <div id="left" class="column">left</div> <div id="right" class="column">right</div> 复制代码
css引入伪类和伪元素概念是为了格式化文档树以外的信息。也就是说,伪类和伪元素都是用来修饰不在文档树中的部分。
伪类存在的意义是为了通过选择器找到那些不存在DOM树中的信息以及不能被常规CSS选择器获取到的信息。
伪元素用于创建一些不在文档树中的元素,并为其添加样式。比如说,我们可以通过:before来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。常见的伪元素有:::before
,::after
,::first-line
,::first-letter
,::selection
、::placeholder
等
因此,伪类与伪元素的区别在于:有没有创建一个文档树之外的元素。
在实际的开发工作中,我们会看到有人把伪元素写成:after
,这实际是 CSS2 与 CSS3新旧标准的规定不同而导致的。
CSS2 中的伪元素使用1个冒号,在 CSS3 中,为了区分伪类和伪元素,规定伪元素使用2个冒号。所以,对于 CSS2 标准的老伪元素,比如:first-line
,:first-letter
,:before
,:after
,写一个冒号浏览器也能识别,但对于 CSS3 标准的新伪元素,比如::selection,就必须写2个冒号了。
div{ margin: 50px; width: 100px; height: 100px; background: red; } /* 半圆 */ .half-circle{ height: 50px; border-radius: 50px 50px 0 0; } /* 扇形 */ .sector{ border-radius: 100px 0 0; } /* 三角 */ .triangle{ width: 0px; height: 0px; background: none; border: 50px solid red; border-color: red transparent transparent transparent; } /* 梯形 */ .ladder{ width: 50px; height: 0px; background: none; border: 50px solid red; border-color: red transparent transparent transparent; } 复制代码
JS基本有5种简单数据类型:String,Number,Boolean,Null,Undefined。引用数据类型:Object,Array,Function。
在写业务逻辑的时候,经常要用到JS数据类型的判断,面试常见的案例深浅拷贝也要用到数据类型的判断。
console.log(typeof 2); // number console.log(typeof true); // boolean console.log(typeof 'str'); // string console.log(typeof undefined); // undefined console.log(typeof []); // object console.log(typeof {}); // object console.log(typeof function(){}); // function console.log(typeof null); // object 复制代码
优点:能够快速区分基本数据类型 缺点:不能将Object、Array和Null区分,都返回object
console.log(2 instanceof Number); // false console.log(true instanceof Boolean); // false console.log('str' instanceof String); // false console.log([] instanceof Array); // true console.log(function(){} instanceof Function); // true console.log({} instanceof Object); // true 复制代码
优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象 缺点:Number,Boolean,String基本数据类型不能判断
var toString = Object.prototype.toString; console.log(toString.call(2)); //[object Number] console.log(toString.call(true)); //[object Boolean] console.log(toString.call('str')); //[object String] console.log(toString.call([])); //[object Array] console.log(toString.call(function(){})); //[object Function] console.log(toString.call({})); //[object Object] console.log(toString.call(undefined)); //[object Undefined] console.log(toString.call(null)); //[object Null] 复制代码
优点:精准判断数据类型 缺点:写法繁琐不容易记,推荐进行封装后使用
let
为 ES6
新添加申明变量的命令,它类似于 var
,但是有以下不同:
var
声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象let
声明的变量,其作用域为该语句所在的代码块内,不存在变量提升const
声明的变量不允许修改Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。用法:
Null类型也只有一个值,即null。null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。用法
//ES5 function getSum(){} function (){}//匿名函数 //ES6 ()=>{} 复制代码
//ES5 var getSum=function(){} //ES6 let getSum=()=>{} 复制代码
const getSum = new Function('a', 'b' , 'return a + b') 复制代码
JS中的作用域分为两种:全局作用域和函数作用域。函数作用域中定义的变量,只能在函数中调用,外界无法访问。没有块级作用域导致了if或for这样的逻辑语句中定义的变量可以被外界访问,因此ES6中新增了let和const命令来进行块级作用域的声明。
更多作用域的了解可以看JS作用域
简单来说闭包就是在函数里面声明函数,本质上说就是在函数内部和函数外部搭建起一座桥梁,使得子函数可以访问父函数中所有的局部变量,但是反之不可以,这只是闭包的作用之一,另一个作用,则是保护变量不受外界污染,使其一直存在内存中,在工作中我们还是少使用闭包的好,因为闭包太消耗内存,不到万不得已的时候尽量不使用。
更多闭包的内容可以看JS闭包
let arr = [1,'1',2,'2',1,2,'x','y','f','x','y','f']; function unique1(arr){ let result = [arr[0]]; for (let i = 1; i < arr.length; i++) { let item = arr[i]; if(result.indexOf(item) == -1){ result.push(item); } } return result; } console.log(unique1(arr)); 复制代码
更多JS去重的方法JS数组去重
三个函数的作用都是将函数绑定到上下文中,用来改变函数中this的指向;三者的不同点在于语法的不同。
fun.call(thisArg[, arg1[, arg2[, ...]]]) fun.apply(thisArg, [argsArray]) 复制代码
所以apply
和call
的区别是call
方法接受的是若干个参数列表,而apply
接收的是一个包含多个参数的数组。
而bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。
var bindFn = fun.bind(thisArg[, arg1[, arg2[, ...]]]) bindFn() 复制代码
Demos:
var name = 'window'; var sayName = function (param) { console.log('my name is:' + this.name + ',my param is ' + param) }; //my name is:window,my param is window param sayName('window param') var callObj = { name: 'call' }; //my name is:call,my param is call param sayName.call(callObj, 'call param'); var applyObj = { name: 'apply' }; //my name is:apply,my param is apply param sayName.apply(applyObj, ['apply param']); var bindObj = { name: 'bind' } var bindFn = sayName.bind(bindObj, 'bind param') //my name is:bind,my param is bind param bindFn(); 复制代码
==类型转换过程:
经典面试题:[] == ![] 为什么是true
转化步骤:
![]
会被转为为false,因此表达式变成了:[] == false
[] == 0
[]
转为空字符串,因此表达式变成了:'' == 0
0 == 0
浅拷贝
function simpleClone(obj) { var result = {}; for (var i in obj) { result[i] = obj[i]; } return result; } 复制代码
深拷贝,遍历对象中的每一个属性
function deepClone(obj) { let result; if (typeof obj == 'object') { result = isArray(obj) ? [] : {} for (let i in obj) { //isObject(obj[i]) ? deepClone(obj[i]) : obj[i] //多谢"朝歌在掘金"指出,多维数组会有问题 result[i] = isObject(obj[i])||isArray(obj[i])?deepClone(obj[i]):obj[i] } } else { result = obj } return result } function isObject(obj) { return Object.prototype.toString.call(obj) == "[object Object]" } function isArray(obj) { return Object.prototype.toString.call(obj) == "[object Array]" } 复制代码
防抖
function debounce(fn, delay) { let timer = null; return function () { if (timer) clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, arguments); }, delay); } } 复制代码
节流
function throttle(fn, cycle) { let start = Date.now(); let now; let timer; return function () { now = Date.now(); clearTimeout(timer); if (now - start >= cycle) { fn.apply(this, arguments); start = now; } else { timer = setTimeout(() => { fn.apply(this, arguments); }, cycle); } } } 复制代码
名称 | 生命期 | 大小限制 | 与服务器通信 |
---|---|---|---|
cookie | 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 | 4KB | 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 |
localStorage | 除非被清除,否则永久保存 | 5MB | 仅在浏览器中保存,不与服务器通信 |
sessionStorage | 仅在当前会话下有效,关闭页面或浏览器后被清除 | 5MB | 仅在浏览器中保存,不与服务器通信 |
把需要计算的数字升级(乘以10的n次幂)成计算机能够精确识别的整数,等计算完成后再进行降级(除以10的n次幂),即:
(0.1*10 + 0.2*10)/10 == 0.3 //true 复制代码
更多关于浮点数精度处理请看JS中浮点数精度问题
首先创建一个父类
// 定义一个动物类 function Animal(name, color) { // 属性 this.name = name || 'Animal'; this.color = color || ['black']; // 实例方法 this.sleep = function () { console.log(this.name + '正在睡觉!'); } } // 原型方法 Animal.prototype.eat = function (food) { console.log(this.name + '正在吃:' + food); }; 复制代码
new了一个空对象,这个空对象指向Animal并且Cat.prototype指向了这个空对象,这种就是基于原型链的继承。
function Cat(name) { this.name = name || 'tom' } Cat.prototype = new Animal() var cat = new Cat() cat.color.push('red') cat.sleep() //tom正在睡觉! cat.eat('fish') //tom正在吃:fish console.log(cat.color) //["black", "red"] console.log(cat instanceof Animal) //true console.log(cat instanceof Cat) //true var new_cat = new Cat() console.log(new_cat.color) //["black", "red"] 复制代码
function Dog(name) { Animal.call(this) this.name = name || 'mica' } var dog = new Dog() dog.color.push('blue') dog.sleep() // mica正在睡觉! dog.eat('bone') //Uncaught TypeError: dog.eat is not a function console.log(dog.color) //["black", "blue"] console.log(dog instanceof Animal) //false console.log(dog instanceof Dog) //true var new_dog = new Dog() console.log(new_dog.color) //["black"] 复制代码
function Mouse(name){ Animal.call(this) this.name = name || 'jerry' } Mouse.prototype = new Animal() Mouse.prototype.constructor = Mouse var mouse = new Mouse() mouse.color.push('yellow) mouse.sleep() //jerry正在睡觉! mouse.eat('carrot') //jerry正在吃:carrot console.log(mouse instanceof Animal)//true console.log(mouse instanceof Mouse)//true var new_mouse = new Mouse() console.log(new_mouse.color) //["black"] 复制代码
MVC即Model View Controller,简单来说就是通过controller的控制去操作model层的数据,并且返回给view层展示。
MVVM即Model-View-ViewModel,将其中的 View 的状态和行为抽象化,让我们可以将UI和业务逻辑分开。MVVM的优点是低耦合、可重用性、独立开发。
MVVM模式和MVC有些类似,但有以下不同
概括起来,MVVM是由MVC发展而来,通过在Model
之上而在View
之下增加一个非视觉的组件将来自Model
的数据映射到View
中。
vue采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty
劫持data属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data。如果单纯的写成对象形式,就使得所有组件实例共用了一份data,造成了数据污染。
由于Vue会在初始化实例时对属性执行getter/setter
转化,所以属性必须在data
对象上存在才能让Vue将它转换为响应式的。Vue提供了$set方法用来触发视图更新。
export default { data(){ return { obj: { name: 'fei' } } }, mounted(){ this.$set(this.obj, 'sex', 'man') } } 复制代码
v-if 是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换。
所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。
v-model本质上是语法糖,v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件。
所以我们可以v-model进行如下改写:
<input v-model="sth" /> // 等同于 <input :value="sth" @input="sth = $event.target.value" /> 复制代码
这个语法糖必须是固定的,也就是说属性必须为value,方法名必须为:input。
知道了v-model的原理,我们可以在自定义组件上实现v-model。
//Parent <template> {{num}} <Child v-model="num"> </template> export default { data(){ return { num: 0 } } } //Child <template> <div @click="add">Add</div> </template> export default { props: ['value'], methods:{ add(){ this.$emit('input', this.value + 1) } } } 复制代码
高效的更新虚拟DOM
。<transition> <span :key="text">{{ text }}</span> </transition> 复制代码
当text改变时,这个元素的key属性就发生了改变,在渲染更新时,Vue会认为这里新产生了一个元素,而老的元素由于key不存在了,所以会被删除,从而触发了过渡。
在Vue文件中的style标签上有一个特殊的属性,scoped。当一个style标签拥有scoped属性时候,它的css样式只能用于当前的Vue组件,可以使组件的样式不相互污染。如果一个项目的所有style标签都加上了scoped属性,相当于实现了样式的模块化。
scoped属性的实现原理是给每一个dom元素添加了一个独一无二的动态属性,给css选择器额外添加一个对应的属性选择器,来选择组件中的dom。
<template> <div class="box">dom</div> </template> <style lang="scss" scoped> .box{ background:red; } </style> 复制代码
vue将代码转译成如下:
.box[data-v-11c6864c]{ background:red; } <template> <div class="box" data-v-11c6864c>dom</div> </template> 复制代码
scoped虽然避免了组件间样式污染,但是很多时候我们需要修改组件中的某个样式,但是又不想去除scoped属性。
//Parent <template> <div class="wrap"> <Child /> </div> </template> <style lang="scss" scoped> .wrap /deep/ .box{ background: red; } </style> //Child <template> <div class="box"></div> </template> 复制代码
//Parent <template> <div class="wrap"> <Child /> </div> </template> <style lang="scss" scoped> //其他样式 </style> <style lang="scss"> .wrap .box{ background: red; } </style> //Child <template> <div class="box"></div> </template> 复制代码
this.$refs.box
this.$refs.box.msg
this.$refs.box.open()
1.当页面中有某些数据依赖其他数据进行变动的时候,可以使用计算属性computed。
<template>{{fullName}}</template> export default { data(){ return { firstName: 'xie', lastName: 'yu fei', } }, computed:{ fullName: function(){ return this.firstName + ' ' + this.lastName } } } 复制代码
2.watch用于观察和监听页面上的vue实例,如果要在数据变化的同时进行异步操作或者是比较大的开销,那么watch为最佳选择。
<template>{{fullName}}</template> export default { data(){ return { firstName: 'xie', lastName: 'xiao fei', fullName: 'xie xiao fei' } }, watch:{ firstName(val) { this.fullName = val + ' ' + this.lastName }, lastName(val) { this.fullName = this.firstName + ' ' + val } } } 复制代码
即地址栏URL中的#符号,它的特点在于:hash 虽然出现URL中,但不会被包含在HTTP请求中,对后端完全没有影响,不需要后台进行配置,因此改变hash不会重新加载页面。
利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法(需要特定浏览器支持)。history模式改变了路由地址,因为需要后台配置地址。
//main.js import Vue from 'vue' export const eventBus = new Vue() //brother1.vue import eventBus from '@/main.js' export default{ methods: { toBus () { eventBus.$emit('greet', 'hi brother') } } } //brother2 import eventBus from '@/main.js' export default{ mounted(){ eventBus.$on('greet', (msg)=>{ this.msg = msg }) } } 复制代码
// 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); }); 复制代码
重绘(repaint或redraw):当盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来之后,浏览器便把这些原色都按照各自的特性绘制一遍,将内容呈现在页面上。重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
重绘发生在元素的可见的外观被改变,但并没有影响到布局的时候。比如,仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局)
重排(重构/回流/reflow):当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建, 这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。
触发重排的条件:任何页面布局和几何属性的改变都会触发重排:
重排必定会引发重绘,但重绘不一定会引发重排。
GET、POST、HEAD、PUT、DELETE、CONNECT、OPTIONS、TRACE
请求方式 | GET | POST |
---|---|---|
参数位置 | 参数拼接到url的后面 | 参数在请求体中 |
参数大小 | 受限于浏览器url大小,一般不超过32K | 1G |
服务器数据接收 | 接收1次 | 根据数据大小,可分多次接收 |
适用场景 | 从服务器端获取数据 | 向服务器提交数据 |
安全性 | 参数携带在url中,安全性低 | 相对于GET请求,安全性更高 |
更多CORS请看彻底读懂前端跨域CORS
由于浏览器的同源策略限制,不允许跨域请求;但是页面中的 script、img、iframe标签是例外,不受同源策略限制。
Jsonp 就是利用script
标签跨域特性进行请求。
JSONP 的原理就是,先在全局注册一个回调函数,定义回调数据的处理;与服务端约定好一个同名回调函数名,服务端接收到请求后,将返回一段 Javascript,在这段 Javascript 代码中调用了约定好的回调函数,并且将数据作为参数进行传递。当网页接收到这段 Javascript 代码后,就会执行这个回调函数。
JSONP缺点:它只支持GET
请求,而不支持POST
请求等其他类型的HTTP请求。
缓存分为强缓存和协商缓存。强缓存不过服务器,协商缓存需要过服务器,协商缓存返回的状态码是304。两类缓存机制可以同时存在,强缓存的优先级高于协商缓存。当执行强缓存时,如若缓存命中,则直接使用缓存数据库中的数据,不再进行缓存协商。
更多缓存内容请看前端也要懂Http缓存机制
跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表 CSS 混淆,故将跨站脚本攻击缩写为 XSS。恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。
跨站请求伪造(Cross-site request forgery),是伪造请求,冒充用户在站内的正常操作。我们知道,绝大多数网站是通过 cookie 等方式辨识用户身份,再予以授权的。所以要伪造用户的正常操作,最好的方法是通过 XSS 或链接欺骗等途径,让用户在本机(即拥有身份 cookie 的浏览器端)发起用户所不知道的请求。
区别:
http://
起始且默认使用端口80,而HTTPS的URL由https://
起始且默认使用端口4431xx表示客户端应该继续发送请求
2xx表示成功的请求
3xx表示重定向
4xx表示客户端错误
5xx表示服务器错误
更多前端资料请关注公众号【前端壹读】
。整理不易,且看且珍惜。
如果觉得写得还不错,请关注我的掘金主页。更多文章请访问谢小飞的博客
PS:看到评论区好多同学批评我说整理得太简单了,react,webpack,Promise都没有,怎么能算面试题呢?首先感谢大家的评论,我会更加努力整理深入的知识点,其次,前端的东西多而杂,我整理这篇文章花了大概一个月时间,有些基础的知识点我可能工作了一段时间都没有用到过,所以偏向基础一点,请技术大佬忽略本文。
更多内容待续。。。
参考