整理

179 阅读10分钟

HTML

◈ WEB语义化是什么,目的是什么?

用正确的标签做正确的事

目的:

  • 页面结构化,便于开发人员代码的编写,提高开发体验感
  • 利于SEO,便于搜索引擎爬虫爬取有效信息
  • 利于项目的迭代和维护

◈ HTML5新特性?

  • 新增语义化标签(header丶footer丶nav丶section丶aside丶article)
  • 视频<video>,音频<audeo> API
  • 会话存储sessionStorage、本地离线存储localStorage
  • 画布<canvas>
  • 拖放dragdrop API
  • 实时通信webSocket
  • 地理定位Geolocation

◈ W3C的理解?

  • web标准规范要求,正确的标签使用(闭合,嵌套),利于SEO
  • 尽量使用外部引入css和js脚本,达到结构与行为,结构与表现的分离,提高页面渲染速度
  • 样式和标签分离,合理的语义化标签,降低维护成本 遵循w3c制定的web标准,能够使用户浏览者更方便的阅读,让网页开发者之间能有更好的交流

webSocket数据通信协议?

链接

CSS

◈ 什么是盒子模型?

  • 将一个元素看成一个盒子,由content丶padding丶border丶margin组成,
  • w3标准盒子模型:width=content+padding+border
  • EI盒子模型(怪异盒子):width:content

◈ 元素的定位有哪些?

position 属性

属性值:

  • relative 相对定位——相对自身位置定位,不脱离标准文档流
  • absolute 绝对定位——相对 不是默认定位的最近父元素定位,脱离
  • fixed 固定定位——相对浏览器可视窗口定位,脱离
  • static 默认定位——从左到右,从上到下布局

当元素脱离标准文档流,且多层时会有覆盖的情况,可以使用z-index设置改变元素的层叠顺序

◈ css3的新特性有哪些?

  • 圆角边框 border-radius
  • 盒子阴影 box-shadow
  • 文本特效 text-shadow
  • 背景设置 background
  • 渐变 gradient
  • 弹性盒子 flex丶网格布局gird
  • rgba()
  • 媒体查询 @media not/only/all screen/print and 表达式
  • 2D/3D转换transform:定位translate丶旋转rotate丶缩放scale丶倾斜shew
  • 过渡 transition
  • 动画animation:keyName 1s @keyframs keyName{form{} to{}}

◈ 像素单位?

  • px 绝对单位,不同设备px像素不一致;
  • rpx是微信小程序引入的像素单位,小程序编译中会对rpx进行px换算,把屏幕宽度分为750份,1份就1rpx
(相当于把屏幕宽度分为750份,1份就1rpx)
比如iPhone6的屏幕宽度是375px,共有750份像素,375/750=0.5,即1rpx=0.5px

/*
* 转换像素 
* Number 像素值
* type rpxtopx:rpx转为px  pxtorpx:px转为rpx
*/
function convertPixels(Number,type = 'rpxtopx') {
  let deviceWidth = wx.getSystemInfoSync().windowWidth; //获取设备屏幕宽度
  let px = ""
  if(type === "rpxtopx") px = (deviceWidth / 750) * Number(Number)
  else px = (750 / deviceWidth) * Number(Number)
  return Math.floor(px);
}
  • pt 物理像素,绝对单位,固定不会改变 (ios 1pt=1px=2rpx)

自适应单位

  • % 百分比,相对父元素,但不针对字体
  • em 随父元素计算字体font-size大小,如果没设置则跟随浏览器font-size,一般1em=16px
  • rem 1rem相对与html根节点font-size大小
  • vw 随视图宽度分为100份
  • vh 随视图高度氛围100份
  • vmin 随浏览器宽高中比较小的值
  • vmax 随浏览器宽高比较大的值

◈ Sass和Less的区别?

  • Sass和Less都是css预处理器,能够嵌套书写,自定义变量,实现css模块化与复用,便与维护和减少代码冗余
  • 区别:
    • 1.Less的环境比Sass简单,Sass需要配置相应的环境;Less的使用也比Sass简单;
    • 2.处理机制不同:Sass通过服务端处理,Less通过客户端处理,less解析会比较慢;
    • 3.Sass中的变量用$ , Less用@;
    • 4.Sass有进程控制和函数概念;
    函数 @function丶@mixin
    条件 @if丶@else
    循环 @for丶@each丶@while
    继承 @extend
    引用 @import
    
    $red: err; 
    @function widthFn($color) {
      @if $color == err {
        @return red
      }
      @else{
        @return blue;
      }
    }
    .color{ color : widthFn($err)}
    

◈ 如何设置盒子的水平垂直居中?

  • 未设宽高
方法1
父盒子 display:flex;
       justify-content:center; //水平居中-设置主(横)轴上子元素的排列方式
       align-items:center;     // 垂直居中设置侧(纵)轴上子元素的排列方式
       height:100%;            // 垂直居中父盒子需有高度才能显示出来,可设高度为百分比

方法2
父盒子  dispaly:flex;height:100%;
子盒子  margin:auto;
  • 子盒子设宽高
父盒子 position:relative;
子盒子 width:300px;height:100px;
       position: absolute;
       
  方法1: 设置左偏移量 50% - (宽度/2)     设置右偏移量 50% - (高度/2)
       left: calc(50% - 300px / 2);
       top: calc(50% - 100px / 2); 
       
  方法2: 
      left: 50%; top:50%;
      margin-left:calc(-300px / 2);margin-top:calc(-100px / 2);
      
  方法3
      left: 50%; top:50%;transform:translate(-50%,-50%);

◈ 常见的flex和grid布局?

  • 多列子元素自适应排列
方法1  不过此方法有个bug,最后一行的子元素无法和其他保持一致排列,可添加多个子元素<i style="width:子元素宽度"></i>解决,但是不美观
    父元素 
        display: flex;
        justify-content: space-around;
        flex-wrap: wrap; 
     子元素 
        margin: 10px 0;
 
 方法2
     父元素
         display: grid;
         grid-template-columns: repeat(auto-fill, 250px);
         grid-gap:10px 0;	
         justify-content: space-around;
     子元素
         width: 250px; 
         margin: 10px 0;	
  • 三栏布局左右固定宽度中间自适应
    父元素
        display: grid;
        grid-template-columns:50px 1fr 100px;
        grid-template-rows:1fr 50px 50px;
        grid-gap:10px;

◈ overflow 对溢出内容的处理

  • visible 默认值
  • hidden 隐藏溢出的内容且不出现滚动条
  • scroll 隐藏溢出的内容,溢出的内容可通过滚动条呈现
  • auto 自适应

◈ Css的优先级?

!Important > style内联样式 >权重值

权重值:id-100 > class-10 > 标签-1,如果权重值相同,遵循就近原则

◈ display:none与visibility:hidden的区别?

  • 前者是操作节点的渲染和卸载,卸载后不占据位置 (无继承性)
  • 后者是对节点的显示和隐藏,隐藏后节点还存在   (具有继承性)

◈ 如何画一条0.5的线?

transform: scale(0.5)

◈ 如何使用css画一个三角形?

设置块级元素的宽高为0,设置元素边框宽度10px,再将另外三边边框设为transparent透明色

◈ 深度选择器?

父类名 /deep/ 子类名{}
父类名 >>> 子类名{}
父类名 ::v-deep 子类名{}

javaScript

◈ js编译原理

js代码无法直接执行,需要通过js编译器编译后才能识别,然后通过js引擎运行执行

  • 编译器对代码进行分解成词法单元,比如let num=1, 分解成let,num,=,1;
  • 再将词法单元解析成AST语法树(抽象语法树)

image.png

  • 代码生成:由Js引擎把AST语法树再次转换,转换成可执行代码

◈ js执行机制?

js的特点就是单线程,任务无法同步执行,这会导致js执行的时长过长,页面渲染慢

程序里面可以分为同步和异步,(异步会被引擎放到任务列队,当引擎认为异步任务能执行了就会进入主线程执行; 排到异步任务后面的代码不用等异步任务结束,会马上执行)

执行机制

  • 先执行 执行栈中的同步任务;
  • 异步任务放入任务队列中;
  • 一旦执行栈中所有同步任务执行完毕,系统会按此次序读取任务列队中的异步任务,于是被读取的异步任务结束 等待状态,进入执行栈开始执行.

◈ var丶let丶const的区别?

  • 声明与初始值的设置
    varlet声明为变量,不用设置初始值,可重复声明
    const 声明为常量,一旦赋值不可变更,不可重复声明
  • 变量提升
    var有变量提升,声明之前使用会获取到undefined
    letconst没有变量提升,声明之前使用会造成暂时性死区,进而报错
  • 作用域
    全局作用域: 函数外的var声明
    局部作用域:函数内的var声明
    块级作用域:{}内声明的letconst
               if,for语句中的letconst声明也属于块级作用域

◈ es6的新特性?

es6的新特性

  • let丶const与块级作用域
  • 解构赋值: 从数组和对象中提取值,对变量进行赋值
  • 模板字符串
  • 数组扩展
    展开运算符
    for...of 遍历
    Array.of() 将类数组转为真正的数组
    Array.of() 将一组值转换为数组
    Array.find() 查找元素,返回符合条件的第一个元素,没有则返回undefined
    Array.findIndex() 查找元素,返回符合条件的第一个元素下标,没有则返回-1
    fill(填充值,start,end) 填充一个数组
    includes() 查询数组中是否含有指定的值,返回Boolean
    flat()/flatMap() 拉平数组(一层/多层)
  • 对象的扩展
    属性和方法的简写
    for...in 遍历
    Object.assign(target,…sources) 合并对象(浅拷贝)
    Object.keys()  返回对象的所有属性名,数据类型为Array
    Object.values() 返回对象的所有属性值
    key in object 检测object中是否有指定的key值,返回布尔值
    super 关键字
  • set 类数组,成员都是唯一的
  • Map 类似对象,对象的映射
  • 函数的扩展
    函数的参数可设默认值
    rest参数 function(...rest){} 将参数转为数组数据格式
    箭头函数
    尾调:函数最后一步是调用另外一个函数
    尾递归
  • Promise 异步的操作同步流程化
  • Symbol es6的引入的新的一种基本数据类型,表示独一无二的值
  • Proxy 在目标对象之前设置一层拦截, 用于修改某些操作的默认行为
  • Calss
  • async函数
  • Module

◈ new 操作符具体做了什么?四步

  • 1.创建一个新的实例对象;
  • 2.设置原型链,将新对象与构造函数通过原型链连接起来;
  • 3.构造函数的this指向新对象,且执行函数体给新对象添加属性和方法;
  • 4.判断返回类型,返回值(如果是值类型返回新对象,如果是引用数据类型则返回构造函数里的对象).

◈ this的理解?

  • this 指针,函数执行时所在的作用域(指向谁,代表谁,等于谁)
  • 一般是指window全局/ 谁调用指向谁
  • 改变this指向有三种方法call丶apply丶bind
call丶apply丶bind的第一个参数都是 this要指向的对象
    区别:
         call 多个枚举传参
         apply 第二个参数为数组进行传参
         bind 弟二个参数为数组进行传参,且需要手动retrun调用(通过声明一个变量存储返回值,然后通过此变量进行调用)
             let fn = Function.bind(this,[value])
             fn()
  • 注意,箭头函数的this和普通函数的this不一样,普通函数在定义时this指向是不确定的,只有在使用的时候谁调用才指向谁
箭头函数在定义时就已经确定
箭头函数要看外层是否有函数,如果有跟随外层函数的this,没有则指向window

◈ 如何理解原型丶原型链?

原型:每个函数都有protoType属性,该属性指向原型对象;

原型链: 每个对象都有原型对象,通过__proto__指向该对象的原型对象,并从中继承方法和属性,同时该原型对象也可能拥有原型,通过原型链一层层向上查找,最终会指向null

作用: 1.实现继承; 2数据共享,节约内存空间

◈ protoType和__proto__的区别?

  • protoType 显式原型: 用来实现原型的继承和属性共享
  • __proto__隐式原型: 构成原型链,同样实现基于原型的继承
区别:
 1.protoType是函数才用的属性,__proto__是每个对象都有的属性;
 2.可通过protoType属性给函数和对象添加(共享丶继承的)的方法和属性
 3.__proto__是查找某个函数或对象的原型链方式
 4.__proto__本质是一个内部属性,不是正式对外api,故得用其他替换
    Object.setPrototypeOf()(写操作)
    Object.getPrototypeOf()(读操作)
    Object.create()(生成操作)代替

◈ 什么是闭包?

闭包就是能够读取到其他函数内部的变量(内部函数访问外部函数的变量,内部函数即为一个闭包)

特点:
 函数嵌套函数;
 内部函数能读取到外部函数的变量;
 参数和变量不会被垃圾回收机制回收,不过这样会造成内存泄漏;(解决办法-清除变量,设为null)

好处: 1可以避免使用全局变量,防止全局变量污染; 
      2.实现封装和缓存.
坏处:内存消耗大,不正当使用会造成内存泄漏.

◈ 了解Class?

  • 通过class定义类,类名首字母大写;
  • 有一个构造函数constructor,用来初始化对象,在new创建对象时自动调用
  • 通过new创建实例化对象
  • 通过extends实现子类继承父类

◈ 什么是事件? 它的执行过程是怎样的?

  • 监听浏览器的操作行为,浏览器触发动作时被捕捉到,然后调用相对应的函数

  • 事件执行三个阶段:事件捕获阶段--处于目标阶段--事件冒泡阶段

  • 事件捕获阶段是自上而下,而冒泡型事件是自下而上的,通常我们需要处理的是第二个阶段,完成事件的动作

 阻止事件冒泡的方式
     e.cancebubble()或者 return false
 阻止默认行为的方式
     e.preventDefault()
     
 在vue中
     .stop 阻止事件冒泡冒泡
     .prevent 阻止默认行为
     .once 事件只触发一次
     .capture 先执行父,再执行子
     .self  只执行子

◈ event事件源,target和currentTarget的区别?

前者是触发事件的元素

后者是绑定事件的元素

◈ 了解Ajax吗?

1. 通过new创建一个XMLHttpRequest对象
    let XHR = ""
    if(window.XMLHttpRequest){ 
        XHR = new XMLHttpRequest();
    }else if(window.ActiveXObject){ //  兼容ie5,ie6
        XHR = new ActiveXObject("Microsoft.XMLHTTP");
    }
2.通过open()建立请求
    XMLHttpRequest对象.open(method,URL,async ,name,password);
        method - get丶post
        URL - 提交的目标地址
        async - 布尔值,true表示异步、false表示同步,默认ture
        用户名 - 如果服务器需要验证,则必须使用该参数
        密码 - 如果服务器需要验证,则必须使用该参数
3.通过send(data) 发送请求,如果请求方式为post则需要添加data数据

4.onreadystatechange  当XHR对象的状态发生变化时触发的函数

5.readyState XHR对象的状态码 
      0 - 未初始化,创建XHR对象时,对象的状态是未初始化的状态
      1 - 初始化,创建完对象后使用open()方法创建了http请求时
      2 - 发送数据,通过send()发送数据处于发送数据状态
      3 - 接受数据,Web服务器接受完数据并进行处理完毕后想客户端返回结果,对象处于接受数据状态
      4 - 完成状态,对象接受数据完毕后,进入完成状态.
      
6.responseText 接受数据 (responseText或responseXml属性)
XHR.onreadystatechange = function(){
    if(XHR.readyState==4 && XHR.status==200){
        console.log(XHR.responseText || XHR.responseXml)
    }
}

◈ JSON格式是什么?

是一种轻量级的数据交互格式,格式为{}包括,键值对的格式,JSON数据结构简单易于读写,占用内存小,是前后端常用的一种数据交互格式

  • JSON.stringify() 对象转为JSON字符串
  • JSON.parse() JSON字符串转为对象

Vue

◈ 生命周期?

  • beforeCreate(创建前): 创建了vue实例,但data和methods还未初始化,为undefined;
  • created(创建后): 初始化data和methods,可调用,但还没有渲染模板
  • beforeMount(挂载前): 编译模板,render函数首次被调用生成vdom虚拟DOM,但是还没渲染上去;
  • mounted(挂载后): 渲染DOM
  • beforeUpdate(更新前): 数据发生改变触发,但DOM为更新,为更新做准备;
  • updated(更新后): DOM重新渲染更新完毕;
  • beforeDestory(销毁前): 在实例销毁前之前调用,一般在这里进行清除定时器,解绑全局事件,清除Storage缓存等操作;
  • destory(销毁后): 实例销毁后调用,组件实例的指令会被解除,所有事件侦听器比移除,子实例被卸载;
  • activated: keep-alive缓存组件激活时调用
  • deactivated: keep-alive缓存组件被缓存时调用
  • errorCaptured: 捕获一个后台组件的错误时调用
1.哪个生命周期可以进行异步请求?
一般在created中,能更快获取服务端数据,减少loading时间

◈ keep-alive内置组件的作用?

  • 为什么会用到此标签:vue会主动卸载掉不使用的组件
  • 它是一个内置组件,不会出现在DOM中,一般用来包裹<router-view>视图标签,作用是第一次加载渲染后组件会缓存到到内存中而不是直接销毁,以避免反复重新渲染导致的性能问题
三个属性:
  1.include 只缓存名称匹配的组件;
  2.exclude 名称匹配的组件不会被缓存;
  3.max  最多可以缓存多少个组件实例
两个生命钩子
  1.activated keep-alive缓存组件激活时调用
  2.deactivated keep-alive缓存组件被缓存时调用
  
有这两个生命钩子函数是因为 keep-alive使得组件不会被销毁和重新创建,所以不会触发

◈ Vue双向绑定原理?

数据劫持+观察者模式(发布者+订阅者模式)

通过object.defineProperty()对数据进行getter和setter拦截处理,在渲染时如果用到了data中每个数据,这个数据会被依赖收集进watcher监听里,当数据发生变化时会被监听并且通知订阅者,调用updated生命周期进行更新

  • 数据劫持: 通过Object.defindProperty()方法触发getter和setter实现拦截处理 (vue3通过Proxy实现数据劫持)
  • 添加订阅者: 在编译时,会在v-model丶{{}}丶v-bind等指令上绑定的属性添加订阅者
  • 给input添加监听事件,修改值的时候会被监听触发set和get方法并且通知订阅者,调用updated生命周期更新视图

◈ style标签中scoped的作用?

scoped是html5的新属性,是一个布尔值

使用该属性,则会给父元素的class添加上data-v-something,实现组件私有化,只对当前组件css起效果,类似形成了一个作用域的效果,不污染全局

设置了scoped后如果想父组件中修改子组件的样式会导致没有效果,可使用深度选择器::v-deep的方式进行穿透

◈ watch丶computed丶methods的区别?

  • watch: 对象,以键值对的形式,键:观察的表达式,值:回调函数,有新旧两个参数

    可监听data中数据的变化,也可监听router

    用来监听特定数据的变化,进行具体的业务逻辑操作

  • computed: 属性名调用,通过return返回结果,结果具有缓存

    对data 数据有依赖性,当函数内依赖的响应式数据发生变化时才会重新被调用计算

    因为具有缓存性,一般是用来处理比较复杂的逻辑操作

  • methods: 函数调用,可以接受参数,没有缓存

◈ key的作用?

使用v-for是需要通过设置key作为当前节点的唯一标识符,以此来取消就地复用原则,如果不设置可能会有节点渲染错乱的情况,以及添加key能使得虚拟dom通过diff算法两两对比更高效

◈ vue中的虚拟dom原理?

  • 状态的变化首先是先作用在虚拟dom上,最终才映射到真实的dom上
1. 提供了和真实的dom相对应的虚拟dom vnode
2. 将虚拟dom vnode和旧的虚拟dom oldnode通过patch算法的核心diff算法进行对比,判断哪些节点发生变化,针对发生变化的节点进行更新操作
3. 最后将更新的虚拟dom映射到真实的dom上

优点:无需操作真实的dom,减少服务器压力

缺点:无法进行极致优化

◈ 权限按钮的实现?

  • 菜单权限根据用户角色不同动态变化: 动态路由根据hidden的布尔值进行菜单栏数据过滤,在beforeEach全局路由守卫中,router.addRoutes()动态添加可访问路由,component路由懒加载注册组件且合并登录404等组件,存储在vuex中作为导航菜单
  • 页面部分功能权限: 通过install(Vue,option){ Vue.directive(name,回调函数) }
3个回调函数
bind 指令与元素绑定成功时
inserted 指令所在元素被插入页面时
update 指令所在模板结构被重新解析时

回调函数的参数
第一个 el 绑定的元素
第二个 可拿到当前页面插入的指令值

通过后台接口获取指令数据集合用vuex存储起来,然后Vue.directive(name,inserted(el,binding){})

binding获取value页面的指定指令值,获取vuex数据通过includes进行查询是否有这个页面指令值,有则返回true,无则返回false且移除当前节点el.parentNode.removeChild(el);

Vue.use(install);

◈ $router$route?

  • $router为VueRouter的实例,是一个全局路由对象,包含了路由跳转的方法、钩子函数等。
  • $route 是路由信息对象||跳转的路由对象,每一个路由都会有一个route对象,是一个局部对象,包含path,params,hash,query,fullPath,matched,name等路由信息参数。

◈ nextTick()?

在下一次dom更新循环结束之后执行的延迟回调

◈ Vue中template模板引擎的渲染过程做了什么?

解析模板为render函数,触发响应式,监听data中的getter和setter,然后执行render函数,生成虚拟dom vnode和执行patch,编译后的vnode会直接替换掉真实dom

◈ 什么是Vuex?

  • Vue.js 的一个状态管理模式,数据是共享的,并且没有大小限制,而且具有响应式的。用户信息、token、购物车信息,都可以用状态管理存储。
状态管理有5个核心概念

state状态数据,类似vue 对象的data属性,是响应式的;
getter类似计算属性,缓存依赖状态数据的变化;
mutation采用同步的方式操作状态管理,使用commit()调用函数;
action采用异步的方式操作状态管理,使用dispatch()来调用;
module状态管理数据较多时,通过模块来划分,避免代码臃肿。

◈ SPA(单页面应用)首屏加载速度慢如何解决?

从两方面出发,资源加载优化、页面渲染优化

  • 减少入口文件体积:路由懒加载;
  • 静态资源本地缓存:合理利用locolStorage;
  • 文件图片资源压缩合并;
  • 使用SSR(服务端渲染);
  • Ui框架按需引入加载

浏览器

◈ 在浏览器输入url后发生什么?

  • url解析: 判断输入的是一个合法的url还是待搜索的关键词,并根据输入内容进行解析

image.png

  • DNS查询: 地址栏域名并不是资源的真实位置,只是ip的映射,域名解析是对域名进行解析还原为ip地址的过程
  • TCP链接(3次握手): 获取到ip地址后,开始建立链接
    第一次握手:建立连接时,客户端发送SYN包到服务器,
    第二次握手:服务器接受syn包,同时发送标有SYN+ACK的数据包
    第三次握手:客户端接受SYN+ACK包,发送标有ACK的数据包,此包发送完毕,
  • HTTP请求: 浏览器向服务器发送http请求
  • 响应请求
  • 页面渲染
  • 断开TCP链接(4次挥手)
1.客户端认为数据发送完成,向服务器发送一个FIN释放连接请求
2.服务端收到释放请求后,发送ACK
3.服务端继续发送剩下的数据,完毕后向客户端发送连接释放请求
4.客户端收到释放请求后向服务端发送ACK确认应答

◈ 浏览器的渲染机制?

  • 渲染引擎解析HTML文档,根据标签构建DOM节点;
  • 解析css文件构建渲染CSSOM (CSS Object Model,即css对象模型);
  • 进入布局阶段,浏览器将DOM和CSSOM结合,计算每个可见元素的布局,构建render tree(比如display:none不会被构建在该树种);
  • 绘制----将最终的渲染树渲染到屏幕上.

◈ 状态码

2xx (成功)
200 客户端请求成功
204 服务器成功处理了请求,但没有返回任何内容

3xx (重定向)
304 自从上一次后请求的页面未修改,服务器返回此响应,不会返回网页内容

4xx (请求错误)
400 错误请求,服务器不理解请求的语法
401 未授权,请求要求身份验证(http认证),当返回此状态码进行token刷新请求
403 服务器拒绝请求访问
404 服务器找不到请求的页面

5xx (服务器错误)
500 服务器内部错误,
502 网络错误
503 网络不可用,超载或停机维护
504 网络超时

◈ hash和history的实现原理和区别? abstract模式了解吗?

hash: 指url中#后面的值,是通过location.hash实现的

  • 在请求的时候不会被包含在http中,每次改变hash不会重新加载页面
  • hash的改变会触发hashchange事件
  • hash的变化会被浏览器记录,实现浏览器的前进后退

history: html5新增的api,用来实现URL的变化

  • 页面请求时会带上整个链接,需要后端做相应的处理,否则会报404
  • history的改变会触发popstate事件
  • history的api有history.pushState()新增新的历史记录丶history.replaceState()替换当前url记录
window.history.back()  // 后退
window.history.forward() // 前进
window.history.go() // 前进或者后退

需要注意,因为history是html5新增的api,所以history其实有兼容性问题

abstract模式

  • 适用于所有js环境,如果没有浏览器api,路由器将自动强行进入此模式

◈ 什么是SSR?服务端渲染

由后端将html字符串拼接好,返给客户端,浏览器拿到这个html文件后可以直接显示,如果是在vue中需通过v-html来渲染显示

优点:首次加载快、利于SEO引擎抓取;
缺点:不易维护,通常前端修改部分html或者css,后端也需要修改
      增加项目复杂度(前后端耦合,互相依赖)对服务器压力较大。

前端

◈ 前端的缓存有哪些?它们的区别?

1.http强缓存采用响应头中的Cache-Control和Expires字段进行控制

  • Cache-Control:
    max-age  指定设置缓存最大的有效时间(单位为s)  
    public   指定响应会被缓存,并且在多用户间共享  
    private  响应只作为私有的缓存,不能在用户间共享  
    no-cache 指定不缓存响应,表明资源不进行缓存  
    no-store 绝对禁止缓存
  • Expires: 缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点, 需要和Last-modified结合使用

2.浏览器缓存:SessionStorage丶LocalStorage丶Cookie

  • LocalStorage 生命周期是永久的,除非手动删除,作用域在所有的同源窗口中是共享的,存储容量5M
  • SessionStorage 生命周期为当前浏览器窗口关闭即数据清空,作用域仅限于本窗口,多个窗口存储数据是不相同的,存储容量5M
  • Cookie 生命周期取决于设置的时间,如果没有设置时间则关闭浏览器即结束,作用域在所有的同源窗口中是共享的,存储容量4k,另外http每次请求都会把cookie数据发送出去

◈ 有没有处理过各个浏览器的兼容性?

1.html

  • 不同浏览器的标签内外边距默认值不同,通过*通用符设置内外边距为0进行初始化;

2.css

  • 块级标签设置float浮动后,如果再设置左右margin时,margin比实际设置的大2倍,页面布局可能会将后一个块级盒子挤到第二行,设置display:inline;转为行内属性;
  • 有的浏览器多个图片标签放一起会有2像素间距问题
1. 设置float浮动
2. 设置display:block; 将内联元素变为块级元素
3. 设置font-size:0;
  • 对于低版本ie浏览器,使用hack处理兼容(即给特定的前缀)
hack是根据不同的浏览器内核在属性添加布套的前缀

苹果谷歌 -webkit-
火狐 -moz-
ie  -ms-
Opera -o-
ie6~ie7 *或者+
ie6~ie10 属性添加后缀/9
  • min-height不兼容,加上一个height

3.js

  • Ajax通过new创建实例对象差异 XMLHttpRequest/activeXObject
  • 绑定方法函数addEventListener/attachEvent
  • window.event,事件源获取的目标对象方式差异,event.target/event.srcElement
  • new Date()中获取年份的差异,getFullYear()/getYear()