web前端面试题

JS部分

如何取消http请求

XHR : .abort() 取消之后执行else
ajax : .abort() 取消之后执行error
axios: CancelToken.source()

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // 处理错误
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
})

TCP和UDP的区别

UDP是用户数据传输协议,无连接,首部开销小,速度快,但是容易丢包,可靠性低,可以实现一对多多对多;
TCP是传输控制协议,面向连接的,不会产生丢包等情况,首部开销大,相对UDP 传输速度较慢,可靠性高,全双工通信信道。只能点到点。

TCP三次握手 四次挥手

  • TCP报文头部
    16位源端口号,16位目标端口号
    32位序号:seq
    32位确认序号:ack
  • TCP的标志位
    SYN(synchronous):建立联机
    ACK(acknowledgement):确认
    FIN(finish):结束

三次握手:

客户端发起一个连接请求,带着标识符SYN=1,seq=J;
服务端接收到这个请求,并响应,返回了一个ACK =1,SYN=1的应答,ack=J+1,seq=K;
客户端收到这个ACK,和SYN后,发送ACK=接收到的SYN的值,ack=K+1返回给服务端,确认信息成功,就可以开始互相发送数据了;

我:(发送消息)小明能收到消息吗,收到回复111
小明:(收到消息了)收到,111,你能收到吗,收到回复666
我:(收到并回复)收到收到666

流程图:
C-S:发送SYN=1,seq=J
C端关闭━主动打开,S端关闭━被动打开
S-C:发送ACK=1,SYN=1,ack=J+1,seq=K
S端处于监听状态,C端处于同步已发送状态
C-S:发送ACK=1,ack=K+1
C端建立连接,S端建立连接
web前端面试题

四次挥手:

客户端发起一个终止请求FIN=1,seq=x;
服务端响应(我知道你想干嘛了,等我一下)ACK=1,ack=x+1;
服务端响应(我好了,关吧关吧)FIN=1,seq=y;
客户端响应ACK=1,seq=y+1;

我:妈我要出门啦
妈:哦,等一下
妈:给你两百块,去玩吧
我:好的,拜拜

流程图:
C-S:FIN=1,seq=x
C建立连接状态━终止等待1,S端建立连接到━关闭等待
S-C:ACK=1,ack=x+1
S关闭等待持续,C终止等待1━终止等待2
S-C:FIN=1,seq=y
C端终止等待━时间等待,S最后确认
C-S:ACK=1,seq=y+1
C端时间等待持续一会后关闭,S端关闭
web前端面试题

缓存

强缓存
协商缓存
304 200
ETag:hash md5 更新
请求头cache-control

响应式布局 自适应布局

  • @media screen :媒体查询
  • rem 根据根节点的font-size来调节;em通过父元素字体大小来调节;
    // 确定根节点字体大小,结合rem实现响应式
    (function(a, d) {
       var b = a.documentElement,
       	e = "orientationchange" in window ? "orientationchange" : "resize",
       	c = function() {
       		var a = b.clientWidth;
       		a && (b.style.fontSize = Math.min(a, 750) / 375 * 100 + "px")
       	};
       a.addEventListener && (d.addEventListener(e, c, !1), 
       a.addEventListener("DOMContentLoaded", c, !1))
    })(document, window);
    
  • vw 通过视口的宽高来确定
  • % 根据父元素的宽高的百分比
  • flex 兼容IE10+
  • grid 兼容IE10+

闭包

闭包,mdn给的释义是函数与其周围此法环境的捆绑,可以访问*变量;你不知道的JavaScript中定义的是能够记住并访问到当前作用域,那么就产生了闭包。闭包的作用有二:一是保存变量,二是保护外部变量不受污染,像柯里化函数,回调函数,模块化等都是闭包的实际应用

cookie、session、local storage, session storage

cookie : 同源请求都能拿到,存取没有其他两个方便 需要用document.cookie去获取在进行匹配,cookie可以设置过期时间

  getCookie: function (name) {
    var arr;
    var reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
    if (arr = document.cookie.match(reg)) {
        return unescape(arr[2]);
    } else {
        return null;
    }
  },
  setCookie:function (name, value, day) {
      if (day !== 0) { //当设置的时间等于0时,不设置expires属性,cookie在浏览器关闭后删除
        var expires = day * 24 * 60 * 60 * 1000;
        var date = new Date(+new Date() + expires);
        document.cookie = name + "=" + escape(value) + ((day == null) ? "" : ";expires=" + date.toGMTString()) + ';path=/;';
      } else {
          document.cookie = name + "=" + escape(value);
      }
  },

sessionstorage过期时间 : 关闭浏览器页面即过期;
localstorage 存储于本地域名下,永久有效,当然也可以自己加一个过期时间 存取时比较

getItem(name)
setItem(name,value)

跨域是怎么产生的,如何解决

非同源的网址,需要从 不同协议 不同域名 不同端口 的网址下去请求资源,就会产生跨域的问题。

解决办法:

  1. Nginx反向代理 :客户端找代理服务器请求资源,代理服务器反向拿到数据给客户端
  2. 添加响应头access-control-allow-origin
  3. jsonp:
    通常为了减轻web服务器的负载,我们把js、css、图片等静态资源分离到另一*立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许。html中有的标签天然支持跨域,比如<script src="http://www.baidu.com"></script>但是只支持get请求。

XSS、CSFR、防暴刷

XSS跨站脚本攻击
是指攻击者在网站上注入恶意客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式
分类: 存储型 反射型
防御:转义 请求头添加x-xss-protection
CSFR跨站请求伪造:在url后加入一些恶意的参数,从而达到攻击者的目的。
防御:禁止第三方请求携带本站cookie 请求加token验证 请求头添加X-Frame-Options

原型原型链

JS原型就是prototype,函数中除了箭头函数都有这个原型属性,对象的原型可以通过__proto__来访问,在函数执行中,若要访问某个变量的成员,那么就会通过原型链来查找,所谓原型链就是以当前对象为起点开始,找到当前对象的原型,原型的原型…直到最终找到基类Objetc.__proto__也就是null停止,当你想扩展原型方法时的时候可以直接加到prototype,不可枚举的,instancof也是基于原型来判断实例是否属于某一个类的。

JS同步异步 事件循环

JS是单线程的脚本语言,也就是说浏览器新开一个页面时,就相当于新开了一个进程,这里只会分一个线程给JS引擎渲染,还会分其他线程用于GPU渲染,HTTP请求等,所以说JS加载顺序就是自上而下进行的,js中的异步是通过EventLoop来实现的,js中的大部分代码都是同步代码,但是像定时器,http请求,promise.then等,都是异步代码,在执行中会先等待同步任务执行完,在进行异步微任务的执行,执行完异步微任务就继续异步宏任务,进行一个事件循环

git

web前端面试题

权限

web前端面试题

你都做过哪些Vue的性能优化?

编码阶段:
尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
如果需要使用v-for给每项元素绑定事件时使用事件代理
SPA 页面采用keep-alive缓存组件
在更多的情况下,使用v-if替代v-show
key保证唯一
使用路由懒加载、异步组件
防抖、节流
第三方模块按需导入
长列表滚动到可视区域动态加载
图片懒加载
SEO优化
预渲染
服务端渲染SSR
打包优化:
压缩代码
Tree Shaking/Scope Hoisting
使用cdn加载第三方模块
多线程打包happypack
splitChunks抽离公共文件
sourceMap优化
用户体验
骨架屏
PWA
还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启gzip压缩等。
(优化是个大工程,会涉及很多方面,这里申请另开一个专栏)

前端如何进行seo优化

合理的title、description、keywords:搜索对着三项的权重逐个减小,title值强调重点即可;description把页面内容高度概括,不可过分堆砌关键词;keywords列举出重要关键词。
语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页
重要内容HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,保证重要内容一定会被抓取
重要内容不要用js输出:爬虫不会执行js获取内容
少用iframe:搜索引擎不会抓取iframe中的内容
非装饰性图片必须加alt
提高网站速度:网站速度是搜索引擎排序的一个重要指标

1000-div问题

一次性插入1000个div,如何优化插入的性能
使用Fragment
var fragment = document.createDocumentFragment();
fragment.appendChild(elem);
向1000个并排的div元素中,插入一个平级的div元素,如何优化插入的性能
先display:none 然后插入 再display:block
赋予key,然后使用virtual-dom,先render,然后diff,最后patch
脱离文档流,用GPU去渲染,开启硬件加速

上一篇:1、Linux--相关软件安装与网络配置


下一篇:Python语言特性之4:类变量和实例变量