渲染过程
输入网址,浏览器交给浏览器进程开始处理你输入的内容
执行 beforeUnload 事件,卸载当前页面
如果不是网址,则开始跳到默认搜索引擎,执行搜索
如果是网址,判断是否存在缓存,是的话,读取缓存并渲染,否则向服务器发送请求
之后把控制权交给网络进程
网络进程会开始执行 DNS 解析,获取 IP地址,并开始建立连接 计算机网络
请求会发送到对方服务器,然后 交给 nginx 进行处理 (如果有负载均衡,会发送到各地对应的服务器进行处理)
建立连接
HTTP连接
客户端发送SYN到服务器
服务器接收到SYN,并生成ACK,发送给客户端
客户端接收到服务的的SYN和ACK,标志连接建立成功
HTTPS连接
客户端发送支持的加密协议和版本给服务端
Client Hello
服务端找到适合的加密协议
Server hello
服务端返回证书和公钥
客户端使用根证书验证证书合法性,生成对称密钥,通过证书的公钥加密,发送给服务端
服务端使用私钥解密,获取对称密钥,使用对称密钥加密数据
客户端解密数据,建立SSL连接
连接建立完成后,浏览器开始读取服务器返回的数据
读取 HTTP 或者 HTTPS 响应的状态码
是否返回 301 和 302,如果是,浏览器将读取HTTP的 Location 字段,执行重定向,并 执行 beforeUnload 之后的过程
返回200,开始读取 Content-Type 字段,判断文件 MIMIE 类型
并根据MIMIE 构建其他请求进行请求渲染
返回404,nginx 是否有404 页面 或者 自定义 nginx 404 内容
没有,执行浏览器默认的异常
有,nginx 返回相关数据,开始渲染
其他异常
所有数据传输完成,断开连接
HTTP
客户端发送FIN=1到服务器
服务端接收到之后,发送ACK到客户端,进入等待关闭状态,此时仍然可以发送接收数据
服务端发送FIN=1,表示数据已经发送完成
客户端收到内容,断开连接
HTTPS
客户端断开连接,发送close_notify
渲染过程,将交给渲染进程 和 GPU 进程去负责
解析的过程,其实是根据相关语义,通过词法分析和语法分析,开始构建 Token,如果不合法,将会在解析过程抛出异常
解析HTML,构建DOM树
解析CSS,构建styleSheets (可以通过document.styleSheets 查看浏览器解析好的一个 CSS 结构)
合并HTML、CSS,生成render tree
根据生成好的 render tree,计算每个节点的层级、transform等,并生成layout tree
浏览器执行完分层后,会开始执行光栅化,并对每个渲染区域进行分块,这里浏览器做了优化。(渲染的时候,并不是全部都渲染的,由于内容过多,所以浏览器只会渲染可视区域的部分)
重绘 Repaint
只改变颜色,不改变位置、宽高的被称作重绘
重排(回流) Reflow
导致元素宽高、位置发生变化的被称为重排,重排一定会触发重绘
浏览器通过显卡把需要显示的内容发送给显示器,显示器读取缓冲区的内容,根据逐行扫描的方式进行渲染
渲染完成
其他问题
在渲染过程中,CSS是否会阻塞渲染,还有js?
在渲染过程中,css会阻塞渲染,但不会阻塞解析,应该是因为需要计算样式的原因
js一定会阻塞解析和渲染,设置了async的script会并行下载,并立即执行,defer 会在dom解析的时候下载,但是会等完成后再去执行
所以head内的js尽量不要操作dom,也不要放,不然会等js下载执行完成才会继续解析dom,造成白屏
css解析规则是啥样的?
css解析规则是从后往前进行解析的,这样的好处就是可以最快的找到被选择的样式,如果从前往后解析,可能会导致解析到一半发现不对,会再次重新解析。
缓存 (建议收藏)为什么第二次打开页面快?五步吃透前端缓存,让页面飞起 (juejin.cn)
强缓存
通过判断Expires和Cache-Control,如果可以缓存,返回200
Expires
HTTP1.0的缓存方式,一个绝对时间
Cache-Control Cache-Control - HTTP | MDN (mozilla.org)
public(可以被服务器和中间服务器缓存)
max-age=1000(表示n秒内可以读取该缓存)
private
只能被服务器缓存
no-cache
和服务器协商判断该文件是否可被缓存,但是不缓存过期的
no-store
不缓存所有数据
协商缓存
通过If-None-Match和If-Modified-Since进行判断,如果返回304,使用缓存,否则返回200,优先使用Etag进行判断,否则使用Last-Modified进行判断。
Etag可以准确的表示文件是否发生变化,而Last-Modified针对短时间内多次更改可能会造成缓存失效。Etag具有强弱之分,以W开头的为弱Etag,表示使用弱验证器,比较容易生成
If-None-Match
携带Etag向服务器进行请求,判读是否可被缓存
If-Modified-Since
携带Last-Modified向服务器进行请求,判断是否可被缓存
启发式缓存
如果响应头没有Expires、Cache-Control:max-age或Cache-Control: s-maxage,并且响应头不包含其他缓存的限制,就可以使用启发式缓存计算有效期,通常根据响应头中的Date字段(报文创建时间)减去Last-Modified值的10%作为缓存时间
缓存位置
缓存策略
浏览器决定,优先使用memory cache,然后使用disk cache
memory cache
读取速度快,适合小文件
disk cache
读取速度慢,适合大文件
service worker
push cache
http2新增,当以上3种缓存都没命中之后使用,只会存在seession中,一旦会话结束就被释放,所以时间很短,并且只能被使用一次
跨域
原因
跨域主要是因为同源策略所引起的,同源策略要求域名、协议、端口三者一样属于同源
解决方案
CORS 跨源资源共享(CORS) - HTTP | MDN (mozilla.org)
Access-Control-Allow-Origin(设置哪些地址可以访问,*为所有,多个域名通过,隔开)
Access-Control-Allow-Headers(允许的请求Headers,多个,隔开)
Access-Control-Allow-Methods(允许的请求方式,多个通过,隔开)
Access-Control-Allow-Credentials(是否允许cookie,值为true和false,同时需要设置HTTP的same-site不能为none)
Access-Control-Expose-Headers(设置浏览器可以获取到的headers)
简单请求
请求方式是head、get、post 3种之一
HTTP头部不超过Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type
Content-Type为: application/x-www-form-urlencoded、multipart/form-data、text/plain
复杂请求
非简单请求就是复杂请求,复杂请求POST会发送一个OPTIONS预检请求,判断服务器是否支持该请求方式,如果为OPTIONS请求,服务器应该返回204
nginx反向代理
document.domain
postMessage
jsonp
进程
渲染进程
GPU进程
浏览器进程
插件进程
web安全
跨站脚本攻击 XSS(Cross Site scripting)
介绍
是指恶意攻击者往Web页面里插入恶意 script 代码,当用户浏览该页之时,嵌入其中Web里面的script代码会被执行,从而达到恶意攻击用户的目的
分类
反射型(持久形)
存储型(非持久形)
DOM型
攻击方式
通过xx方式,恶意注入代码,然后被执行
防御
对输入内容进行校验,并对一些字符做转义处理
跨站脚本漏洞(XSS)基础讲解
跨站请求伪造 CSRF(Cross-site request forgery)
介绍
通过登录授信网站,并在本地生成cookie, 在不退出的情况下,去访问危险网站,就会收到攻击
防御
检查 http 的 Referer 字段,判断是否同域名下
服务端生成一个随机的 token,每次请求的时候,服务端都去校验当前token是否过期
内容安全策略 CSP(Content Security Policy)
用于检测某些特定的攻击类型,包括XSS和数据注入,HTTP需要返回Content-Security-Policy,对浏览器内的资源进行检查
浏览器引擎
webkit 苹果
blink 谷歌
gecko 火狐



