1、从输入url到页面显示出来发生了什么
1.DNS解析
2.TCP连接
3.发送HTTP请求
4.服务器处理请求并返回需要的数据
5.浏览器解析渲染页面
解析HTML,生成DOM树,解析CSS,生成CSSOM树
将DOM树和CSSOM树结合,生成渲染树(Render Tree)
Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
Display:将像素发送给GPU,展示在页面上
6.连接结束
2、http状态码的了解
- 1xx(临时响应)
表示临时响应并需要请求者继续执行操作的状态代码
- 2xx (成功)
表示成功处理了请求的状态码。
例:200 – 服务器成功返回网页
- 3xx (重定向)
表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向
例:
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
- 4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理。
例:404 – 请求的网页不存在
- 5xx(服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
例:
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
3、http2.0的优点
- 解析速度快
服务器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段。
- 多路复用
- HTTP1.1 如果要同时发起多个请求,就得建立多个 TCP 连接,因为一个 TCP 连接同时只能处理一个 HTTP1.1 的请求。
- 在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。同一个请求和响应用一个流来表示,并有唯一的流 ID 来标识。 多个请求和响应在 TCP 连接中可以乱序发送,到达目的地后再通过流 ID 重新组建。
- 首部压缩
HTTP2 提供了首部压缩功能。多请求请求时,有很多消息头都是重复的。如果可以把相同的首部存储起来,仅发送它们之间不同的部分,就可以节省不少的流量,加快请求的时间。
HTTP/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送。如果服务器收到了请求,它会照样创建一张表。 当客户端发送下一个请求的时候,如果首部相同,它可以直接发送这样的首部块:服务器会查找先前建立的表格,并把这些数字还原成索引对应的完整首部。
- 优先级
HTTP2 可以对比较紧急的请求设置一个较高的优先级,服务器在收到这样的请求后,可以优先处理。
- 流量控制
由于一个 TCP 连接流量带宽(根据客户端到服务器的网络带宽而定)是固定的,当有多个请求并发时,一个请求占的流量多,另一个请求占的流量就会少。流量控制可以对不同的流的流量进行精确控制。
- 服务器推送
HTTP2 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。换句话说,除了对最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确地请求。
4、cookie,localStorage和sessionStorage的区别
- cookie可以设置失效时间,但没有自己的存取取的方法,在服务端写入,每次请求时跟随请求发送,大小为4K
- localStorage有自己的存取方法,可以做长期存储大小为5M
- sessionStorage有自己的存取方法,关闭页面即情况缓存,大小为5M
5、设计模式知道那些?具体用法
- 单例模式:就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。
- 观察者模式: 观察者的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。
- 工厂模式解决了重复实例化的问题,缺点,创建不同对象其中属性和方法都会重复建立,消耗内存;还有函数识别问题等等。
6、知道XSS(跨站脚本攻击)和CSRF(跨站请求伪造)吗
- XSS(跨站脚本攻击)
XSS 是一种注入攻击,其目的是在网站上植入恶意Javascript代码,然后当用户浏览这个网站时,恶意脚本就会在用户的浏览器上运行,以获取用户信息或执行恶意操作。
措施:
1、验证 HTTP Referer 字段
2、添加token验证
- CSRF(跨站请求伪造)
利用的是用户对恶意网站的权限,攻击者会在用户浏览某个网站时,通过伪装成一个受信任的网站发送请求,CSRF 通过利用用户的身份信息,从而让用户无意识地执行恶意操作。这些操作通常是由第三方发起的,而用户并不知情。
措施:
1、输入过滤
2、输出转义
3、使用 HttpOnly Cookie
7、Seo是什么?怎么优化?
引擎优化。是一种方式:利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名。
- 优化:
1、SSR服务器渲染
2、预渲染prerender-spa-plugin
3、的title、description、keywords
4、化的HTML代码,符合W3C规范
5、饰性图片必须加alt
6、外链
7、向各大搜索引擎提交收录自己的站点
8、原生ajax的交互过程
先创建XHR对象即XMLHttpRequest()
然后open准备发送,open中有三个参数一是提交方式get和post,二是接口地址,三是同步和异步
第三步是用send发送
第四步再发送的过程中通过onreadystatechange来监听接收的回调函数,可以通过判断readyState==4和status==200来判断是否成功返回,然后通过responseText接收成功返回的数据
9、数组常用方法、用法是什么?
push,pop,unshift,shift,splice,join,concat,forEach,filter,map,sort,some,every
10、数组排序
11、数组去重
第一种:利用ES6的set来实现 例如:[…new Set(arr)]
第二种:借用临时对象的方式
12、JS事件代理(也称事件委托)是什么,及实现原理
JS事件代理就是通过给父级元素(例如:ul)绑定事件,不给子级元素(例如:li)绑定事件,然后当点击子级元素时,通过事件冒泡机制在其绑定的父元素上触发事件处理函数,主要目的是为了提升性能,因为我不用给每个子级元素绑定事件,只给父级元素绑定一次就好了,在原生js里面是通过event对象的targe属性实现
var ul = document.querySelector("ul"); ul.onclick = function(e){//e指event,事件对象 var target = e.target || e.srcElement; //target获取触发事件的目标(li) if(target.nodeName.toLowerCase() == 'li'){//目标(li)节点名转小写字母,不转的话是大写字母 alert(target.innerHTML) } } jq方式实现相对而言简单 $(“ul”).on(“click”,“li”,function(){//事件逻辑}) 其中第二个参数指的是触发事件的具体目标,特别是给动态添加的元素绑定事件,这个特别起作用
13、构造函数、原型、原型链的理解
- 构造函数
构造函数就是一个普通的函数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写。另外就是调用方式的不同,普通函数是直接调用,而构造函数需要使用new关键字来调用。
- 原型
每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。
- 原型链
当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。如果没有则去原型的原型中寻找,直到找到Object对象的原型,Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined。
14、深拷贝、浅拷贝的区别,并实现深拷贝
浅拷贝可以理解为改变一个对象属性值,另一个对象属性也会发生改变,即互相影响,
对象深拷贝即就是说改变一个对象属性,另一个对象属性值不会发生改变,可以通过多种方法来实现对象深拷贝,
浅拷贝方法:
Object.assign
Array.prototype.slice()
,Array.prototype.concat()
- 使用拓展运算符实现的复制
- JSON.stringify和JSON.parse来实现
深拷贝方法:
- jQuery.extend()
- JSON.stringify()
- 手写循环递归
function deepClone(obj) { let objClone = Array.isArray(obj) ? [] : {}; if(obj && typeof obj === 'object') { for(key in obj) { // 判断对象是否包含特定的自身(非继承)属性。 if(obj.hasOwnProperty(key)) { // 判断obj子元素是否为对象,如果是,递归复制 if(obj[key] && typeof obj[key] === 'object') { objClone[key] = deepClone(obj[key]); } else { objClone[key] = obj[key]; } } } } return objClone; } let arr = [1,2,[3,4],5]; let arr1 = arr; let arr2 = deepClone(arr); arr[2][0] = 9; console.log(arr); // [1,2,[9,4],5] console.log(arr1); // [1,2,[9,4],5] 可以看到改变 arr 后 arr1 的值也改变了; console.log(arr2); // [1,2,[3,4],5]
核心思想:引用数据类型是有基本数据类型构成的,并且,基本数据类型是不存在深浅拷贝这一说的,那么我们只需要将引用数据类型的每一层次的基本数据类型赋值,并遍历到最深处的基本数据并赋值就可以完成深拷贝。
15、JS原生事件如何绑定
JS原生绑定事件主要为三种:
一是html事件处理程序
例如:点我
二是DOM0级事件处理程序
例如:
var btn=document.getElementById(‘id元素’) btn.οnclick=function() { //要处理的事件逻辑 }
三是DOM2级事件处理程序
例如: var btn=document.getElementById(‘id元素’)
//绑定事件
btn.addEventListener(‘click’,绑定的事件处理函数名,false)
//移除事件
btn.removeEventListener(‘click’,要移除的事件处理函数名,false)