1、请说说从用户输入url到呈现网页,这中间都发生了什么 ?
1、域名解析
域名解析的过程:
1).查询浏览器自身DNS缓存
2).若上面没有查找到,则搜索操作系统自身的dns缓存
3).若上面没有找到,则尝试读取hosts文件
4).若上面没有找到,向本地配置的首选DNS服务器发送请求
5).win系统 如果上面没有找到,操作系统查找NetBIOS name cache
6).win系统 如果上面没有找到,查询wins服务器
7).win系统 如果上面没有找到,广播查找
8).win系统 如果上面没有找到,读取LMHOSTS文件
若以上多没有找到,解析失败
2、 TCP三次握手
a. 为什么需要三次握手
下面解释明明两次就可以建立连接的为什么还要加第三次的确认。
如果发送两次就可以建立连接话,那么只要客户端发送一个连接请求,服务端接收到并发送了确认,就会建立一个连接。
可能出现的问题:如果一个连接请求在网络中跑的慢,超时了,这时客户端会从发请求,但是这个跑的慢的请求最后还是跑到了,然后服务端就接收了两个连接请求,然后全部回应就会创建两个连接,浪费资源!
如果加了第三次客户端确认,客户端在接受到一个服务端连接确认请求后,后面再接收到的连接确认请求就可以抛弃不管了。
b. 为什么需要四次分手
TCP是双向的,所以需要在两个方向分别关闭,每个方向的关闭又需要请求和确认,所以一共就4次。
3、浏览器向服务器发送http请求
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET/sample/hello.jsp HTTP/1.1。
4、浏览器发送请求头信息
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。
5、服务器处理请求
服务器软件收到http请求,确定执行什么(ASP.net PHP RUBY JAVA等)来处理他。读取参数并进行逻辑操作后,生成指定的数据。
6、服务器做出应答
客户机向服务器发出请求后,服务器会客户机回送应答,HTTP/1.1 200 OK ,应答的第一部分是协议的版本号和应答状态吗
7、服务器发送应答头信息
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。
8、服务器发送数据
Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据。
9、tcp连接关闭
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:
Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽
2、请说说浏览器渲染页面的过程 ?
分析:这道题的考察点重点在于浏览器渲染页面的机制上面,只有充分理解渲染机制以后才能去更好的优化咱们的页面,比如css为什么放到head里面,js为什么放到body后面,重绘重排概念
参考回答: 浏览器渲染页面是一个从上至下的过程,当拿到html以后首先会生成dom树,加载解析css构建cssom树,解析css的时候不会阻塞进程,我们通常会把首屏样式放到head里面,然后加载执行js,在js里面可能会有动态创建修改dom的逻辑,浏览器为了优化整个渲染过程,会在解析到js的时候阻塞整个进程,我们通常把js放到body后面来优化首屏的加载速度,当dom以及cssom都构建完成后会生成渲染树,再根据渲染树将dom树上的节点布局到屏幕上的正确位置,最后遍历绘制的所有节点,为其添加对应的样式
延伸理解
重绘:改变dom的外观属性,如背景色,outline等
重排: 改变dom的结构,几何属性等
为了减少浏览器的重排重绘,我们应该将多次改变样式的操作合并成一次操作
3、说说http,https的区别,他们的优缺点是什么?
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
一、HTTP和HTTPS的基本概念
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
二、HTTP与HTTPS有什么区别?
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。
简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
三、HTTPS的工作原理
我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。
1、客户端发起HTTPS请求
这个没什么好说的,就是用户在浏览器里输入一个https网址,然后连接到server的443端口。
2、服务端的配置
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。
这套证书其实就是一对公钥和私钥,如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。
3、传送证书
这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。
4、客户端解析证书
这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。
如果证书没有问题,那么就生成一个随机值,然后用证书对该随机值进行加密,就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。
5、传送加密信息
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
6、服务段解密信息
服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。
7、传输加密后的信息
这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。
8、客户端解密信息
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容,整个过程第三方即使监听到了数据,也束手无策。
六、HTTPS的优点
正是由于HTTPS非常的安全,攻击者无法从中找到下手的地方,从站长的角度来说,HTTPS的优点有以下2点:
1、SEO方面
谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名将会更高”。
2、安全性
尽管HTTPS并非绝对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻击,但HTTPS仍是现行架构下最安全的解决方案,主要有以下几个好处:
(1)、使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
(2)、HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
(3)、HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
七、HTTPS的缺点
虽然说HTTPS有很大的优势,但其相对来说,还是有些不足之处的,具体来说,有以下2点:
1、SEO方面
据ACM CoNEXT数据显示,使用HTTPS协议会使页面的加载时间延长近50%,增加10%到20%的耗电,此外,HTTPS协议还会影响缓存,增加数据开销和功耗,甚至已有安全措施也会受到影响也会因此而受到影响。
而且HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。
最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行。
2、经济方面
(1)、SSL证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
(2)、SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗(SSL有扩展可以部分解决这个问题,但是比较麻烦,而且要求浏览器、操作系统支持,Windows XP就不支持这个扩展,考虑到XP的装机量,这个特性几乎没用)。
(3)、HTTPS连接缓存不如HTTP高效,大流量网站如非必要也不会采用,流量成本太高。
(4)、HTTPS连接服务器端资源占用高很多,支持访客稍多的网站需要投入更大的成本,如果全部采用HTTPS,基于大部分计算资源闲置的假设的VPS的平均成本会上去。
(5)、HTTPS协议握手阶段比较费时,对网站的相应速度有负面影响,如非必要,没有理由牺牲用户体验。
4、请说说js里的this的指向
参考回答:
js中this的指向总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的, 而非函数被声明时的环境
具体到实际应用中,this 的指向大致可以分为以下几种
* 作为对象的方法调用指向当前对象
* 作为普通函数调用指向全局window
* 构造函数调用指向返回的对象
* call,apply 调用指向其第一个参数
5、怎么理解js中的原型链?如何实现继承?
参考回答:
每个构造函数都有一个原型对象
每个原型对象都包含一个指向构造函数的指针
每个实例都包含一个指向原型对象的指针
查找方式是一层层向上查找直至顶层Object.prototype
实现继承的方式常用的有:
原型链继承
借用构造函数(call,apply)
组合继承(原型链+构造函数)
原型式继承
寄生式组合式继承
延伸理解:
优缺点?
每一种继承的方式都有自己的优缺点
组合继承的特点是会调用构造函数两次,
都是将多种继承方式组合到一起相辅相成.
new 运算符具体干了什么?
创建一个空的对象
将空的对象的__proto__成员指向构造函数的prototype成员对象
调用构造函数将this指向前面创建的对象
6、Js中的内存泄露怎么理解?
参考回答:
内存泄漏的定义为当程序不再需要的内存,由于某种原因其不会返回到操作系统或可用内存池,内存泄漏会导致一系列问题,比如: 运行缓慢,崩溃,高延迟等
js中常见的内存泄露:
意外的全局变量
遗忘的计时器或回调函数
脱离文档的DOM引用
闭包
7、如何理解浏览器的跨域问题?常用的解决方式有哪些?
参考回答:
浏览器的同源策略会导致跨域,这里同源策略又分为以下两种 :
DOM同源策略:禁止对不同源页面DOM进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
XmlHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。只要协议、域名、端口有任何一个不同,都被当作是不同的域,之间的请求就是跨域操作
注:协议、域名、端口有任何一个不同,都视为不同的域
常用的解决方式:
1.CORS(Cross-origin resource sharing) 跨域资源共享
注: 这种方式如果想要携带cookie需要xhr设置withCredentials为true, 服务端 Access-Control-Allow-Credentials:true
2.jsonp实现跨域(动态创建script,利用src属性进行跨域)
3.服务器代理(浏览器有跨域限制,服务端没有)
4.document.domain
5.window.name
6.hash传值
7.possMessage
8、函数防抖,函数节流的基本概念以及工作中实际使用到的场景?实现的思路是?
函数防抖,函数节流的基本概念以及工作中实际使用到的场景?实现的思路是?
参考回答:
函数防抖(debounce)
基本概念: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
举例理解: 我们用手指一直按住一个弹簧,它将不会马上弹起直到你松手为止
使用场景:
按钮重复点击
输入框连续输入
判断scroll是否滑到底部
简单实现:
const debounce = (fn,delay) => {
let timer = null
return () => {
let ctx = this, args = arguments
clearTimeout(timer)
timer = setTimeout( ()=> {
fn.apply(ctx,args)
}, delay)
}
}
函数节流(throttle)
基本概念: 在规定的时间范围内相同的操作触发多次只执行一次
DOM拖拽
Canvas画笔
窗口resize
简单实现:
const throttle = (fn,gapTime = 100) => {
let timer = null
let start_time = new Date().getTime()
return () => {
let ctx = this, args = arguments,
current_time = new Date().getTime()
clearTimeout(timer)
if(curr_time - start_time >= gapTime()){
fn.apply(ctx,args)
start_time = current_time
}else{
timer = setTimeout( ()=> {
fn.apply(ctx,args)
}, gapTime)
}
}
}
9、说说js中的eventloop机制?
参考回答:
首先javascript是单线程机制,就是指当我们在执行一个任务的时候,其它的事情都得等待他执行完毕
在js中所有任务分为两种, 同步任务及异步任务
执行栈执行主线程任务,当有操作dom,ajax交互,使用定时器异步操作的时候,这些任务会被移入到 callback queue 任务队列中 当主线程任务执行完毕为空时,会读取callback queue队列中的函数,进入主线程执行 上述过程会不断重复,也就是常说的Event Loop(事件循环)
在一个事件循环中,异步任务返回结果后会被扔进一个任务列队中,根据异步事件上的类型,这个事件会被放到对应的宏任务或者微任务列队中去, 当执行栈为空的时候,主线程会先查看微任务中的事件列队,如果微任务不是空先依次执行微任务,如果是空的再去宏任务列队中取出一个事件并把对应的回调加入到当前执行栈,如此反复,进入循环
下面用一道题来加深印象
setTimeout(function () {
console.log(1);
});
new Promise( (resolve,reject) => {
console.log(2)
}).then( (val) => {
console.log(val);
})
输出的结果是2,1
10、web安全攻击手段有哪些?以及如何防范
常见的有xss, csrf, sql注入
xss(cross site scripting) 跨站脚本攻击
定义: 指攻击者在网页嵌入脚本,用户浏览网页触发恶意脚本执行
XSS攻击分为3类:存储型(持久型)、反射型(非持久型)、基于DOM
如何防范:
设置HttpOnly以避免cookie劫持的危险
过滤,对诸如<script>、<img>、<a>等标签进行过滤
编码,像一些常见的符号,如<>在输入的时候要对其进行转换编码
限制,对于一些可以预期的输入可以通过限制长度强制截断来进行防御
csrf(cross site request forgery) 跨站请求伪造
定义: 是一种劫持受信任用户向服务器发送非预期请求的攻击方式
如何防范:
验证 HTTP Referer 字段
请求地址中添加 token 并验证
HTTP 头中自定义属性并验证
sql注入(SQL injection)
定义: 在未授权情况下,非法访问数据库信息
如何防范:
杜绝用户提交的参数入库并且执行
在代码层,不准出现sql语句
在web输入参数处,对所有的参数做sql转义
上线测试,需要使用sql自动注入工具进行所有的页面sql注入测试
11、说说你对前端模块化的理解。
模块的定义:
可以理解成实现特定功能的相互独立的一组方法
为什么要使用模块化:
可维护性
命名空间
可复用性
模块化规范
CommonJS
AMD
UMD
CMD
Module(es6)
CommonJS
CommonJS 扩展了JavaScript声明模块的API,
通过CommonJS,每个JS文件独立地存储它模块的内容(就像一个被括起来的闭包一样)。在这种作用域中,我们通过 module.exports 语句来导出对象为模块,再通过 require 语句来引入
如:
function myModule() {
this.hello = function() {
return 'hello!';
}
}
module.exports = myModule;
AMD (Asynchronous Module Definition)
特点:
提倡依赖前置,在定义模块的时候就要声明其依赖的模块
如:
require([module], callback);
CMD (Common Module Definition)
CMD规范是国内SeaJS的推广过程中产生的
提倡就近依赖(按需加载),在用到某个模块的时候再去require
define(function (require, exports, module) {
var one = require('./one')
one.do()
// 就近依赖,按需加载
var two = require('./two')
two.do()
})
UMD (Universal Module Definition)
AMD和CommonJS的结合,跨平台的解决方案,UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。在判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块
如:
(function (window, factory) {
if (typeof exports === 'object') {
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
define(factory);
} else {
window.eventUtil = factory();
}
})(this, function () {
//module ...
});
Module
原生JS(es6)解决方案
如:
export default myModule
import myModule from './myModule'
12、Call,apply,bind的使用与区别,如何实现一个bind?
相同点:
都是使用于方法借用及明确this指向场景
第一个参数都是this要指向的对象
都可以利用后续参数传参
不同点:
参数传递方式不同
call,apply是立即调用,bind是动态调用
基本使用:
Array.prototype.slice.call(obj,0,1,2)
Array.prototype.slice.apply(obj,[0,1,2])
Array.prototype.slice.bind(obj)(0,1,2)
从上面的例子可以看出来call,apply 使用上几乎保持一致,而bind实际上是返回了一个函数
简易bind实现
Function.prototype.bind = function(context){
const _this = this
return function() {
_this.apply(context, Array.prototype.slice.call(arguments))
}
}
上面的bind只实现了方法的作用域绑定,参数已经固定,如果想要动态的参数我们得改写一下
Function.prototype.bind = function(context){
const _this = this
const argus = Array.prototype.slice.apply(arguments,[1])
return function() {
_this.apply(context, argus.concat(Array.prototype.slice.call(arguments)))
}
}
13、前端的缓存有哪些?都适用什么场景?区别是什么?
参考回答
前端缓存分为两部分:
http 缓存
浏览器缓存
http 缓存
强缓存
强缓存主要是采用响应头中的Cache-Control和Expires两个字段进行控制的
Cache-Control 值理解:
max-age 指定设置缓存最大的有效时间(单位为s)
public 指定响应会被缓存,并且在多用户间共享
private 响应只作为私有的缓存,不能在用户间共享
no-cache 指定不缓存响应,表明资源不进行缓存
no-store 绝对禁止缓存
Expires 理解:
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点, 需要和Last-modified结合使用
Last-modified 理解
服务器端文件的最后修改时间,需要和cache-control共同使用,是检查服务器端资源是否更新的一种方式
ETag 理解
根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改
协商缓存(304)
协商缓存是指当强缓存机制如果检测到缓存失效,就需要进行服务器再验证
浏览器缓存
Cookie
LocalStorage
SessionStorage
Service Worker
Cookie
Cookie主要用于用户信息的存储, 容量为4KB
LocalStorage
LocalStorage的数据将一直保存在浏览器内,直到用户清除浏览器缓存数据为止, 容量为5MB
SessionStorage
SessionStorage的其他属性同LocalStorage, 不同是的当页面关闭时会随之清除
Service Worker
主要是为了提高web app的用户体验,可以实现离线应用消息推送等等一系列的功能, 可以看做是一个独立于浏览器的Javascript代理脚本, 在离线状态下也能提供基本的功能。 出于安全性的考虑,Service Worker 只能在https协议下使用分
14、Http常见状态码及其含义?
http状态码分为5个大类
1** 信息相关
2** 请求成功
3** 重定向相关
4** 客户端错误相关,或无法完成请求
5** 服务端错误相关
301—永久移动。被请求的资源已被永久移动位置;
302—请求的资源现在临时从不同的 URI 响应请求;
305—使用代理。被请求的资源必须通过指定的代理才能被访问;
307—临时跳转。被请求的资源在临时从不同的URL响应请求;
400—错误请求;
402—需要付款。该状态码是为了将来可能的需求而预留的,用于一些数字货币或者是微支付;
403—禁止访问。服务器已经理解请求,但是拒绝执行它;
404—找不到对象。请求失败,资源不存在;
406—不可接受的。请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体;
408—请求超时;
409—冲突。由于和被请求的资源的当前状态之间存在冲突,请求无法完成;
410—遗失的。被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址;
413—响应实体太大。服务器拒绝处理当前请求,请求超过服务器所能处理和允许的最大值。
417—期望失败。在请求头 Expect 中指定的预期内容无法被服务器满足;
418—我是一个茶壶。超文本咖啡罐控制协议,但是并没有被实际的HTTP服务器实现;
420—方法失效。
422—不可处理的实体。请求格式正确,但是由于含有语义错误,无法响应;
500—服务器内部错误。服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理
15、前端优化手段有哪些?
前端优化手段有哪些?
静态资源合并压缩(js,css, images)
请求数量优化
Gzip压缩
带宽优化
CDN
就近节点,减少DNS查找
按需加载
lazyload
减少请求
骨架屏
优化白屏
web缓存
缓存ajax数据
减少重绘和重排
批量更新DOM样式
页面结构
将样式表放在顶部,将脚本放在底部,尽早刷新文档的输出
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。