前端面试之--网络相关
一.WebSocket
WebSocket心跳重连是为了保证链接的可持续性和稳定性。在使用原生的WebSocket的时候,如果设备网络断开,不会触发WebSocket任何事件函数,前端程序无法得知当前链接已经断开。这个时候如果调用WebSocket.send方法,浏览器会发现消息发不出去,便会立即或者一定时间后(不同的浏览器或者浏览器版本不同可能表现不同)触发onclose函数。后端webSocket服务也可能出现异常,连接断开后前端也并没有接收到消息,因此需要前端定时发送心跳消息,后端接受类似的消息立马返回,告知连接正常。如果一定时间没有收到消息,就说明连接异常,前端需要重新连接。为了解决上述问题,以前端为主动方,定时发送给消息,用来检测网络和前后端连接问题。一旦发生异常,前端持续执行重新连接逻辑,直到连接成功。let socket; // websocket实例let lockReconnet = false // 避免重新连接//新建websocket的函数,页面初始化,断开连接时重新调用const getwebsocket = () =>{let wsUrl = 'ws://ip'; // url网址socket = new WebSocket(wsUrl)//绑定一些事件,onerror,onclose, onopen,onmessage//如果希望websocket连接一直保持,可以在close或者error上绑定重连方法// 这样一般正常情况下失去连接时,触发onclose方法,就能重连了socket.onclose = function(event) {console.log("websocket服务出错了')reconnect(wsUrl)}socket.onclose = function(event) {console.log('websocket服务关闭了')reconnect(wsUrl)}socket.open = function(event) {heartCheck.reset().start() // 传递信息}socket.onmessafe = function (event)=>{// 如果获取到消息,心跳检测重置// 拿到任何消息都说明当前连接是正常的console.log('websocket服务获得数据了')// 接受消息后的UI变化doWithMsg(event.data)heartCheck.reset().start()}// 收到消息推送function doWithMsg(msg){// 执行业务代码}
}
// 重新连接
const reconnect = (url) => {if(lockReconnect) returnlockReconnect = true// 没连上会一直重连,设置延迟避免请求过多setTimeout(function() {getwebsocket()lockReconnect = false},2000)}// 心跳检测let hearcheck = {timeout: 60000, // 60秒timeoutObj: null,serverTimeoutObj: null,reset: () => {clearTimeout(this.timeoutObj)clearTimeout(this.serverTimeoutObj)return this},start: ()=>{let _this = this;this.timeoutObj = setTimeout(()=>{// 这里发送一个心跳,后端收到后,返回一个心跳消息// onmessage拿到返回的心跳就说明连接正常socket.send('心跳测试')// 如果超过一定的额事件还没重置,说明后端主动断开了_this.serverTimeoutObj = setTimeout(function(){// 这里再onclose里执行了reconnect// 所以这里检测到超时之后,执行socket.close()就触发了onclose,进而执行了reconnectsocket.close()}, _this.timeout)},this.timeout)}}什么条件下执行心跳?
当onopen连接上时,我们便开始执行。如果在定时时间范围内,onmessage获取到了后端的消息,就重新执行。如果距离上次从后端获取到的消息超过60秒后执行心跳检测,判断下是否断联了,检测时间可以根据时间情况设定。
二.Token一般是存放在哪里?
一般用户通过用户名和密码登录成功后,服务器将登录凭据做数字签名,加密之后得到的字符串作为token。它在用户登录成功后会返回给客户端,客户端主要有这么几种存储方式:1.存储在localStorage中,每次调用接口的时候都把它当作一个字段传给后台。2.存储在cookie中,让它自动发送,不过缺点是不能跨域。3.拿到之后存储在localStorage中,每次调用接口的时候放在HTTP请求头的Authorization字段里,token在客户端一般存放在local Storage,cookie或者sessionStorage中。
三. 在什么情况下会触发options请求?
1.options的作用:用于获取目的资源所支持的通信选项。客户端可以对特定的URL使用options方法,也可以
对整站(通过将URL设置为*)使用该方法。
换言之:可以使用options请求去嗅探某个请求在对应的服务器中都支持哪种请求方法。在跨域的情况下,浏
览器发起复杂请求前会主动发起options请求。跨域共享标准规范要求,对那些可能对服务器数据产生副作用
的http请求方法(特别是get以外的http请求,或者搭配某些MIME类型的POST请求),浏览器必须首先使用
options方法发起一个预见请求,从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的
http请求。
2.不会触发cors预检请求一般为简单请求,触发预检请求称为复杂请求。
3.简单请求类别:满足以下条件的请求为简单请求(1 请求方法:get post head(2 除了以下请求头字段之外,没有自定义的请求头:AcceptAccent-LanguageContent-LanguageContent-TypeDPRDownlinkSave-DataViewport-WidthWidth(3 Content-Type的值仅限于下列三者之一:text/planmultipart/form-dataapplication/x-www-urlencoded(4 请求中的任意的XMLHttpRequestUpload对象均没有注册任何事件监听器;XMLHttpRequestUpload对象可以使用XMLHttpRequest.upload属性访问。(5 请求中没有使用ReadableStream对象。4.复杂请求类别: 即非简单请求就是复杂请求。复杂请求我们也可以称之为实际进行请求前,需要发起预检请求的请求。需预检的请求必要首先使用options方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。预检请求的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。跨域请求时,options请求触发的条件:(1 使用了下面任意http方法:put delete connect options trace patch(2 人为设置了以下集合之外的首部字段: Accept Accept-Language Content-Language Content-Type DPR Downlink Save-Data Viewport-Wdith Width(3 Content-Type:的值不属于下列之一:application/x-www-form-urlencoded multipart/form-data text/plain
四.对服务端渲染SSR了解多少?
1.概念:服务端渲染是数据与模板组成的html,即html = 数据 + 模板。将数组或页面通过服务器生成html字符串,再发送到 浏览器,最后将静态标记混合为客户端上完全交互的应用程序。页面没有使用服务渲染,当请求页面时,返回的body里为空,之后执行js将html结构注入到body里,结合css显示出来。
2.优势:a.所有的模板,图片等资源都存在服务器端;b.一个html返回所有的数据;c.减少http请求;d.响应快,用户体验好,受屏渲染快。e.非常利于SEO:seo不同于爬虫工作原理,只会爬取源码,不会执行网站的任何脚本(google除外,Google可以运行js)。使用React或者其他MVVM框架之后,页面大多数DOM元素都实在客户端根据js动态生成,可供爬虫抓取分析的内容大大减少。另外,浏览器爬虫不会等待我们的数据抓取完成后再抓取页面数据。服务端渲染返回给客户端的是已经获取了异步数据并执行js脚本的最终html,网络爬虫就可以抓取到更完整的页面信息。f.更利于首屏渲染:首屏的渲染时node发送过来的html字符串,并不依赖于js文件了,使用客户就会更快地看到页面的内容,尤其是针对大型单页面应用,打包后文件体积比较大,普通客户端渲染加载所有所需文件时间较长,首页就会有一个很长的白屏等待时间。
3.劣势:a.服务端压力较大:本来时通过客户端完成渲染的,现在统一到服务端node服务去做。尤其时高并发访问的情况,会大量占用服务端CPU资源。b.开发条件受限:在服务端渲染中,只会执行到componentDidMount之前的生命周期钩子,因此项目引用的第三方的库也不可用其他生命周期,这对引用库的选择产生了很大的限制。c.学习成本相对较高除了对webpack,MVVM框架要熟悉,还需要掌握node,koa2等相关技术。相对于客户端渲染,项目构建,部署过程更为复杂。4.耗时比较:a.数据请求由服务端请求首屏数据,而不是客户端请求首屏数据,比较快。服务端在内网进行请求,数据响应速度快。客户端在不同网络环境进行数据请求,并且外网http请求开销大,导致时间差大。b.html渲染服务端渲染时先向后端服务器请求数据,然后生成完整首屏html返回给浏览器;客户端渲染是等js代码下载,加载,解析完成之后在请求数据渲染,等待的过程页面是什么都没有的,就是用户所看到的白屏。服务端渲染不需要等待js代码下载完成并请求数据,就可以返回一个已有完整的数据首屏页面。
五.说一下什么是运营商劫持?有什么预防措施?
- 什么是运营商?
运营商是指那些提供宽带服务的ISP,包括三大运营商中国电信,中国移动,中国联通,还有一些小运营商,比如长城宽带,歌华有线等。运营商提供最基础的网络服务,掌握着通往用户物理大门的钥匙。
- 运营商劫持
运营商劫持常见的有两种:DNS劫持和HTTTP劫持。DNS(Domain Name System),域名系统,可将域名和IP地址相互映射的一个分布式数据库。1.DNS劫持有三种情况:a.错误域名解析到纠错导航页面,导航页面存在广告。判断方法:访问的域名是错误的,而且跳转的导航页也是官方是我,譬如电信的114,联通移网域名纠错导航页面。b.错误域名解析到非正常页面,对错误的域名解析到导航页的基础上,有一定几率解析到一些恶意站点,这些恶意站点通过判断你访问的目标HOST,URI,referrer等来确定是否跳转广告页面,这种情况就有可能导致跳转广告页面(域名输错)或者访问页面被加广告(页面加载时有些元素的域名错误而触发),这种劫持会对用户访问的目标HOST,URI,referrrer等会进行判定来确定是否解析恶意站点地址,不易被发现。c.直接将特点站点解析到恶意或者广告页面,这种情况比较恶劣,而且出现这种情况未必就是运营商所为,家里路由器被黑或者系统入侵,甚至运营商的某些节点被第三方恶意控制都有可能。
2.HTTP劫持:DNS解析的域名ip地址不变,但是在和网站交互的过程中劫持了请求。
- 防劫持措施
目前运营商劫持率是3%~25%,防劫持措施如下:1.全站HTTPS,能防一部分;2.加入防运营劫持代码,能防大部分注入型劫持;3.记录log,记录证据,向工信部投诉。
- 防劫持代码
<meta charset="utf-8">
<title>防劫持代码测试</title>
<script>
console.log("发生劫持,初始化就直接置顶的流氓行为,暂无法防御,但可以通过埋点记录LOG,向工信部投诉");
</script>
<!--防劫持-->
<script shendun-eddy>
/**
*@note 防劫持代码
*@key MutationObserver 提供了监视对DOM树所做更改的能力
**/
(function(){ var srcFilterTags = ["script","iframe"];// 域名白名单 可以加多个var whiteList = ["zeptojs.com"];var whiteListReg = [];// 正则匹配whiteList.forEach(function(wl){// shendun-eddy是script白名单标签if(addedNode.src==="" && addedNode.getAttribute("shendun-eddy") !== null){return true;}var isInWhiteList = false;whiteListReg.forEach(function(wReg){if(wlReg.test(addedNode.src)){isInWhiteList = true;return false;}});return isInWhilte;}// dom观察var mutationHandler = function(records){records.forEach(function(record){Array.prototype.slice.call(record.addedNodes).forEach(function(addedNode){srcFilterTags.forEach(function(tagName){// 标签匹配 白名单匹配if(addedNode.tagName === tagName.toUpperCase() && !inWhileList(addedNode)){addedName.remove();}});});}); }// 核心- MutationObserver 提供了监视对DOM树所做更改的能力;// 优点-动态监听是否有非法的iframe和script代码// 缺点-无法查找头部直接插入的代码var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;observeMutationSupport = !!MutationObserver;var html = document.getElementsByTagName("html")[0];if(observerMutationSupport){new MutationObserver(mutationHAndler).observe(html,{childList: true,subtree: true});}// 唯独直接加载的不能remove掉,异步加载的都能remove掉// 记录头部的script,通知工信部var eleList = document.querySelectAll("script");var len = eleList.length;for(var i = 0; i < len; i++){// 遍历操作if(!inWhileList(eleList[i])){/** do sth 这里删除虽然晚了,因为头部同步js已被执行,删除操作意义不大,但可以统计被劫持的代码是什么,记录好Log通知工信部 **/// senLogeleList[i].remove();}}})();</script><script>console.log("劫持");</script></head></body>
// 防劫持代码测试
<script src="https://mt.cnzz.com/js/hdpi_canvas.js"></script>
<script src="http://zeptojs.com/zepto.min.js"></script>
<script src="http://yun.dui88.com/qiho-h5/jqg/shendun_test.js"></script>
<script> console.log("劫持…."); </script> </body> </html> ```
/**加入运营商劫持代码后,不在白名单和安全标签(shendun-eddy)内的 script 或者 iframe 或者 remove
掉。提示:network 内能看到加载了其他非白名单内的 script 代码,但它们都没有执行。
核心功能
MutationObserver()创建并返回一个新的 MutationObserver 它会在指定的 DOM 发生变化时被调用。
兼容性
所有浏览器代码的兼容性是 92.97%,手机的兼容性更高,代码中加了保护所以可以放心使用。
**/
前端面试之--网络相关相关推荐
- 前端面试中浏览器相关问题(二):回流与重绘
前端面试中浏览器相关问题(二):回流与重绘 文章目录 前端面试中浏览器相关问题(二):回流与重绘 浏览器的渲染过程 生成渲染树 回流 重绘 何时发生回流重绘 浏览器的优化机制 减少回流和重绘 最小化重 ...
- 定时器和promise_web前端面试中 promise 相关
Promise 作为当下主流的异步解决方案,在工作中和面试中常常出现,尤其是在面试中,会弄个场景让你手写代码,这里给大家介绍五道比较有代表性的题目,以便熟悉一些套路. promise 简单介绍 先简单 ...
- 前端开发基础——网络相关(TCP、UDP、HTTP等)
文章目录 网络分层模型 TCP和UDP 什么是TCP/IP.TCP.UDP TCP和UDP的区别 TCP三次握手 TCP四次挥手 HTTP和HTTPS HTTP和HTTPS的区别 HTTP请求头 HT ...
- 前端面试总结 -- 网络基础之 HTTP 和 HTTPS
基本概念 HTTP:超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式.协作式和超媒体信息系统的应用层协议[1].HTTP是万维网的数据通信 ...
- 【运维面试】网络相关的面试题
运维方向对于网络也是有一定的要求的,但在面试的时候其实问的技术点不多.总结下来无非这么几个: OSI,TCP/IP 五层协议的体系结构,以及各层协议 OSI分层 (7层): • 物理层 • 数据链路层 ...
- 前端面试之Vue相关总结
Vue2中检测数组变化的限制和解决方法 vue2用下标设置数组没效果 arr = [1,2] arr[0] = 0,页面上显示的arr并没有修改(如果对应下标是原始值:若是引用值) 解决1:Vue.S ...
- 清除string内容_前端面试之javascript相关内容整理一
1.js有哪些数据类型?(死记就行,好嗨哟) 答:js基本数据类型:String.Number.Boolean.Null.undefined 混合数据类型:Object(Array) 2.手写AJAX ...
- 前端面试知识点整理——网络
前端面试知识点整理--网络 文章目录 一. 进程(process)和线程(thread) 二. 浏览器属于一种多进程的架构 三.CRP,关键渲染路径(critical rendering path) ...
- [前端面试]HTTP相关常问问题
[前端面试]HTTP常问问题 HTTP(HyperText Transfer Protocol)是一种用于在网络上传输超文本的协议.面试中,可能会有以下常见的问题: HTTP 的工作原理 HTTP 的 ...
最新文章
- 发布一个原创的基于Ajax的通用(组合)查询
- linux 进程参数文件 /proc/pid/cmdline 简介
- 【控制】《多智能体系统的协同群集运动控制》陈杰老师-第8章-高阶非线性多智能体分布式自适应鲁棒控制
- java 链表算法_JAVA数据结构与算法之链表(一)
- php中unset函数是在哪一章_PHP unset函数原理及使用方法解析
- 【教育与多媒体技术】
- EL调用java方法
- Nginx windows安装部署
- Vue.js 2.x笔记:指令(4)
- RISC 和 CISC 区别
- :将照片处理成绘画风格
- 34. Element textContent 属性
- 【论文笔记】Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition
- JavaSE——Java8之函数式接口、函数式编程、Lambda表达式
- python输出去掉空格
- 32bit 天堂2服务端多机负载
- python转exe遇到的坑及解决方案
- clock oscillator,generator,buffer选型杂谈
- 什么是b3dm?b3dm详解
- 音频音量调整中的ramp up down