1,浏览器存储的方式有哪些
补充:cookie 原本并不是用来储存的,而是用来与服务端通信的,需要存取请自行封装 api。
而 localStorage 则自带 getItem 和 setItem 方法,使用很方便。
localStorage 注意点:
-
localStorage 只能存字符串,存取 JSON 数据需配合 JSON.stringify() 和 JSON.parse()
-
遇上禁用 setItem 的浏览器,需要使用 try...catch 捕获异常
2,浏览器内核的理解
主要分两个部分: 渲染引擎 、 js引擎
渲染引擎: 负责取得网页的内容(html css img ...),以及计算网页的显示方式,然后会输出至显
示器或者打印机。浏览器的内核不同对于网页的语法解释也不同,所以渲染的效果也不一样
js引擎: 解析和执行javascript 来实现网页的动态效果
最开始渲染引擎和js引擎并没有区分的很明确,后来js引擎越来越独立,内核就倾向于只值渲染引
擎
IE : trident 内核
Firefox : gecko 内核
Safari : webkit 内核
Opera :以前是 presto 内核, Opera 现已改用 Google - Chrome 的 Blink 内核
Chrome:Blink (基于 webkit , Google与Opera Software 共同开发)
3,HTTP 的请求方式场景
Get 方法:获取数据通常(查看数据)-查看
POST 方法:向服务器提交数据通常(创建数据)-create
PUT 方法:向服务器提交数据通常(更新数据)-update,与 POST 方法很像,也是提交数据,但 PUT
制定了资源在服务器上的位置,常用在修改数据
HEAD 方法:只请求页面的首部信息
DELETE 方法:删除服务器上的资源
OPTIONS 方法:用于获取当前 URL 支持的请求方式
TRACE 方法:用于激活一个远程的应用层请求消息回路
CONNECT 方法:把请求链接转换到透明的 TCP/IP 的通道
4,HTTP状态码
1XX:信息状态码
100 continue 继续,一般在发送 post 请求时,已发送了 http header 之后服务端将返回此
信息,表示确认,之后发送具体参数信息
2XX:成功状态码
200 ok 正常返回信息
201 created 请求成功并且服务器创建了新资源
202 accepted 服务器已经接收请求,但尚未处理
3XX:重定向
301 move per 请求的网页已经永久重定向
302 found 临时重定向
303 see other 临时冲重定向,且总是使用get请求新的url
304 not modified 自从上次请求后,请求的网页未修改过
4XX:客户端错误
400 bad request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起
请求
401 unauthorized 请求未授权
403 forbidden 禁止访问
404:not found 找不到如何与url匹配的资源
5XX:服务器错误
500 internal server error 最常见的服务器端的错误
503 service unacailable 服务器端暂时无法处理请求(可能是过载活维护)
5,从浏览器地址栏输入URL后发生了什么?
基础版本
- 的浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP ,向服务器发起请求;
- 服务器交给后台处理完成后返回数据,浏览器接收文件 (
- HTML、JS、CSS 、图象等) ;
- 浏览器对加载到的资源 (
- HTML、JS、CSS 等) 进行语法解析,建立相应的内部数据结构 (如
- HTML 的 DOM ) ;
- 载入解析到的资源文件,渲染页面,完成。
详细版
- 从浏览器接收 url 到开启网络请求线程(这一部分可以展开浏览器的机制以及进程与线程之间的
- 关系)
- 开启网络线程到发出一个完整的 HTTP 请求(这一部分涉及到dns查询, TCP/IP 请求,五层因特
- 网协议栈等知识)
- 从服务器接收到请求到对应后台接收到请求(这一部分可能涉及到负载均衡,安全拦截以及后台内
- 部的处理等等)
- 后台和前台的 HTTP 交互(这一部分包括 HTTP 头部、响应码、报文结构、 cookie 等知识,可以
- 提下静态资源的 cookie 优化,以及编码解码,如 gzip 压缩等)
- 单独拎出来的缓存问题, HTTP 的缓存(这部分包括 http缓存头部 , ETag , catchcontrol
- 等)
- 浏览器接收到 HTTP 数据包后的解析流程(解析 html -词法分析然后解析成 dom 树、解析 css 生成
- css 规则树、合并成 render 树,然后 layout 、 painting 渲染、复合图层的合成、 GPU 绘
- 制、外链资源的处理、 loaded 和 DOMContentLoaded 等)
- CSS 的可视化格式模型(元素的渲染规则,如包含块,控制框, BFC , IFC 等概念)
- JS 引擎解析过程( JS 的解释阶段,预处理阶段,执行阶段生成执行上下文, VO ,作用域链、回
- 收机制等等)
- 其它(可以拓展不同的知识模块,如跨域, web 安全, hybrid 模式等等内容)
详细升级版
- 在浏览器地址栏输入 URL
- 浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤
- 如果资源未缓存,发起新请求
- 如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证。
- 检验新鲜通常有两个HTTP头进行控制 Expires 和 Cache-Control :
- 2.3.1 HTTP1.0 提供 Expires ,值为一个绝对时间表示缓存新鲜日期
- 2.3.2 HTTP1.1 增加了 Cache-Control: max-age= ,值为以秒为单位的最大新鲜时间
- 浏览器解析 URL 获取协议,主机,端口, path
- 浏览器组装一个 HTTP(GET) 请求报文
- 浏览器获取主机ip地址,过程如下:
- 浏览器缓存
- 本机缓存
- hosts文件
- 路由器缓存
- ISP DNS缓存
- DNS递归查询(可能存在负载均衡导致每次IP不一致)
- 打开一个socket与目标IP地址,端口建立TCP链接,三次握手
- 如下:
- 客户端发送一个 TCP的SYN=1,Seq=X 的包到服务器端口
- 服务器发回 SYN=1,ACK=x+1,Seq=Y 的相应包
- 客户端发送 ACK=Y+1,Seq=z
- TCP 链接建立后发送 HTTP 请求
- 服务器接收请求后解析,将请求转发到服务器程序,如虚拟主机使用 HTTP Host 头部判断请求的
- 服务程序
- 服务器检测 HTTP 请求头是否包含缓存验证信息,如果验证缓存新鲜,返回304等对应状态
- 出合理程序读取完整请求并准备 HTTP 相应,可能需要查询数据库等操作
- 服务器将相应报文通过 TCP 链接发送回浏览器
- 浏览器接收HTTP相应,然后根据情况选择关闭TCP链接或者保留重用,关闭TCP链接的四次握手如
- 下:
- 主动方发送 Fin=1,ACK=z,Seq=x 报文
- 被动方发送 ACK=X+1,Seq=Y 报文
- 被动方发送 Fin=1,ACK=X,Seq=Y 报文
- 主动方发送 ACK=Y,Seq=x 报文
- 浏览器检查相应状态码
- 如果资源可缓存,进行缓存
- 对相应进行解码
- 根据资源类型决定如何处理解析 HTML 文档,构建 DOM 树,下载资源,构建 CSSOM 树,执行js脚本,这些操作每月严格的先后
- 顺序
- 构建DOM树:
- Tokenizing:根据HTML规范将字符流解析为标记
- Lexing:词法分析将标记转换为对象并定义属性和规则
- DOM construction:根据HTML标记关系将对象组成DOM树
- 解析过程中遇到图片、样式表、js文件,启动下载
- 构建CSSOM树:
- Tokenizing :字符流转换为标记流
- Node :根据标记创建节点
- CSSOM :节点创建CSSOM树
- 根据 DOM树和CSSOM树 构建渲染树
- 从 DOM树 的根节点遍历所有可见节点,不可见节点包括:1) script , meta 这样本身不可
- 见的标签。2)被css隐藏的节点,如 display: none
- 对每一个可见节点,找到恰当的 CSSOM 规则并应用
- 发布可视节点的内容和计算样式
- js解析如下
- 浏览器创建 Document对象 并解析 HTML ,将解析到的元素和文本节点添加到文档中,此时
- document.readystate为loading
- HTML解析器遇到没有 async和defer的script时 ,将他们添加到文档中,然后执行行内或外
- 部脚本。这些脚本会同步执行,并且在脚本下载和执行时解析器会暂停。这样就可以用
- document.write() 把文本插入到输入流中。同步脚本经常简单定义函数和注册事件处理程
- 序,他们可以遍历和操作script和他们之前的文档内容
- 当解析器遇到设置了 async属性的script 时,开始下载脚本并继续解析文档。脚本会在它下
- 载完成后尽快执行,但是解析器不会停下来等它下载。异步脚本禁止使用
- document.write() ,它们可以访问自己script和之前的文档元素
- 当文档完成解析, document.readState变成interactive
- 所有 defer脚本 会按照在文档出现的顺序执行,延迟脚本能访问完整文档树,禁止使用
- document.write()
- 浏览器在 Document 对象上触发 DOMContentLoaded事件
- 此时文档完全解析完成,浏览器可能还在等待如图片等内容加载,等这些内容完成载入并且所
- 有异步脚本完成载入和执行, document.readState变为complete,window触发load事件
- 显示页面(HTML解析过程中会逐步显示页面)
6,请你谈谈Cookie的优缺点
优点: 极高的扩展性和可用性
-
数据持久性。
-
不需要任何服务器资源。 Cookie 存储在客户端并在发送后由服务器读取。
-
可配置到期规则。 控制 cookie 的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的 cookie
。
-
简单性。 基于文本的轻量结构。
-
通过良好的编程,控制保存在 cookie 中的 session 对象的大小。
-
通过加密和安全传输技术( SSL ),减少 cookie 被破解的可能性。
-
只在 cookie 中存放不敏感数据,即使被盗也不会有重大损失。
缺点:
- Cookie 数量和长度的限制 。
数量:每个域的 cookie 总数有限。
a) IE6 或更低版本最多 20 个 cookie
b) IE7 和之后的版本最后可以有 50 个 cookie
c) Firefox 最多 50 个 cookie
d) chrome 和 Safari 没有做硬性限制
长度:每个 cookie 长度不超过 4KB ( 4096B ),否则会被截掉。
- 潜在的安全风险 。 Cookie 可能被拦截、篡改。如果 cookie 被拦截,就有可能取得所有的 session 信
息。
-
用户配置为禁用 。有些用户禁用了浏览器或客户端设备接受 cookie 的能力,因此限制了这一功能。
-
有些状态不可能保存在客户端 。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数
器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
7,cookies , sessionStorage 和 localStorage 的区别
cookie 是网站为了标示用户身份而储存在用户本地终端上的数据(通常经过加密)
cookie 数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递
(优化点)
sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存
存储大小:
cookie 数据大小不能超过4k
sessionStorage 和 localStorage 虽然也有存储大小的限制,但比 cookie 大得多,可以
达到5M或更大
有期时间:
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据
sessionStorage 数据在当前浏览器窗口关闭后自动删除
cookie 设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭
8,浏览器缓存
浏览器缓存分为强缓存和协商缓存。当客户端请求某个资源时,获取缓存的流程如下
先根据这个资源的一些 http header 判断它是否命中强缓存,如果命中,则直接从本地获取缓存
资源,不会发请求到服务器;
当强缓存没有命中时,客户端会发送请求到服务器,服务器通过另一些 request header 验证这
个资源是否命中协商缓存,称为 http 再验证,如果命中,服务器将请求返回,但不返回资源,而
是告诉客户端直接从缓存中获取,客户端收到返回后就会从缓存中获取资源;
强缓存和协商缓存共同之处在于,如果命中缓存,服务器都不会返回资源; 区别是,强缓存不对发
送请求到服务器,但协商缓存会。
当协商缓存也没命中时,服务器就会将资源发送回客户端。
当 ctrl+f5 强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存;
当 f5 刷新网页时,跳过强缓存,但是会检查协商缓存;
9,浏览器渲染的步骤
-
HTML 解析出 DOM Tree
-
CSS 解析出 Style Rules
-
两者关联生成 Render Tree
-
Layout(布局)根据 Render Tree 计算每个节点的信息
-
Painting 根据计算好的信息进行渲染整个页面
浏览器解析文档的过程中,如果遇到 script 标签,会立即解析脚本,停止解析文档(因为 JS 可能会改变
DOM 和 CSS,如果继续解析会造成浪费)。
如果是外部 script, 会等待脚本下载完成之后在继续解析文档。现在 script 标签增加了 defer 和 async 属
性,脚本解析会将脚本中改变 DOM 和 css 的地方> 解析出来,追加到 DOM Tree 和 Style Rules 上
10,GET 和 POST 请求的区别
GET 参数通过 url 传递,POST 放在 body 中。(http 协议规定,url 在请求头中,所以大小限制很
小)
GET 请求在 url 中传递的参数是有长度限制的,而 POST 没有。原因见上↑↑↑
GET 在浏览器回退时是无害的,而 POST 会再次提交请求
GET 请求会被浏览器主动 cache,而 POST 不会,除非手动设置
GET 比 POST 更不安全,因为参数直接暴露在 url 中,所以不能用来传递敏感信息
对参数的数据类型,GET 只接受 ASCII字符,而 POST 没有限制
GET 请求只能进行 url(x-www-form-urlencoded)编码,而 POST 支持多种编码方式
GET 产生一个 TCP 数据包; POST 产生两个 TCP 数据包。对于 GET 方式的请求,浏览器会把 http
的 header 和 data 一并发送出去,服务器响应200(返回数据)。而对于 POST,浏览器先发送
header,服务器响应100 continue,浏览器再发送 data,服务器响应200 ok(返回数据)
11,什么是reflow
浏览器为了重新渲染部分或整个页面,重新计算页面元素位置和几何结构的进程叫做 reflow . 通俗点说
就是当开发人员定义好了样式后(也包括浏览器的默认样式),浏览器根据这些来计算并根据结果将元素放
到它应该出现的位置上,这个过程叫做 reflow . 由于reflow是一种浏览器中的用户拦截操作,所以我们
了解如何减少 reflow 次数,及DOM的层级,css 效率对 refolw 次数的影响是十分有必要的。 reflow
(回流)是导致DOM脚本执行效率低的关键因素之一,页面上任何一个节点触发了 reflow,会导致它的子
节点及祖先节点重新渲染。 简单解释一下 Reflow:当元素改变的时候,将会影响文档内容或结构,或
元素位置,此过程称为 Reflow。
常见的重排元素
width
height
padding
margin
display
border-width
border
top
position
font-size
float
text-align
overflow-y
font-weight
overflow
left
font-family
line-height
vertical-align
right
clear
white-space
bottom
min-height
当p节点上发生reflow时,hello和body也会重新渲染,甚至h5和ol都会收到影响。
12,什么时候会导致reflow发生呢?
改变窗口大小
改变文字大小
添加/删除样式表
内容的改变,(用户在输入框中写入内容也会)
激活伪类,如:hover
操作class属性
脚本操作DOM
计算offsetWidth和offsetHeight
设置style属性
13,减少reflow对性能的影响
不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className
把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow),然后你修改100次,
然后再把它显示出来
不要把 DOM 结点的属性值放在一个循环里当成循环里的变量
尽可能不要修改影响范围比较大的 DOM
为动画的元素使用绝对定位 absolute / fixed
不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
hello
Name:BDing
male
- coding
- loving
尽可能限制reflow的影响范围,尽可能在低层级的DOM节点上,上述例子中,如果你要改变p的样
式,class就不要加在div上,通过父元素去影响子元素不好。
避免设置大量的 style 属性,因为通过设置 style 属性改变结点样式的话,每一次设置都会触发一
次 reflow,所以最好是使用 class 属性
实现元素的动画,它的position属性,最好是设为absoulte或fixed,这样不会影响其他元素的布局
动画实现的速度的选择。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会
过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
不要使用 table 布局,因为table中某个元素旦触发了 reflow,那么整个 table 的元素都会触发
reflow 。那么在不得已使用 table 的场合,可以设置 table-layout:auto; 或者是 table-layout:fixed
这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围
如果CSS里面有计算表达式,每次都会重新计算一遍,出发一次reflow。