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 三次握手
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 的区别,他们的优缺点是什么?
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、说说你对前端模块化的理解。