【八】浏览器:一个浏览器是如何工作的?(阶段一)
对浏览器的实现者来说,他们做的事情,就是把一个URL变成一个屏幕上显示的网页。
这个过程是这样的:
1.浏览器首先使用HTTP 协议或者HTTPS 协议,向服务端请求页面
2.把请求回来的HTML代码经过解析,构建成DOM树
3.计算DOM树上的CSS属性
4.最后根据CSS属性对元素逐个进行渲染,得到内存中的位图
5.一个可选的步骤是对位图进行合成,这会极大地增加后续绘制的速度
6.合成之后,再绘制到界面上
image.png
从HTTP请求回来,就产生了流式的数据,后续的DOM树构建、CSS计算、渲染、合成、绘制,都是尽可能地流式处理前一步的产出:即不需要等到上一步骤完全结束,就开始处理上一步的输出,这样我们在浏览网页时,才会看到逐步出现的页面。
HTTP协议
浏览器首先就是根据URL把数据取回来,取回数据使用的是HTTP协议,实际上还有DNS查询。
HTTP标注是由IETF组织制定,跟HTTP相关的标准有两份:
HTTP 协议是基于TCP协议出现的,对TCP协议来说,TCP协议是一 条双向的通讯通道,HTTP在TCP的基础上,规定了Request- Response 的模式。这个模式决定了通讯必定是由浏览器端首先发起的。
大部分情况下,浏览器的实现者只需要用一个TCP库,甚至一个现成的HTTP库就可以搞定浏览器的网络通讯部分。HTTP 是纯粹的文本协议,它是规定了使用TCP协议来传输文本格式的一个应用层协议。
HTTP协议格式
HTTP协议格式.png在这些部分中,path是请求的路径完全由服务端来定义,没有很多的特别内容;而version几乎都是固定字符串;response body是我们最熟悉的HTML。
HTTP Method(方法)
先说一下request line里面的方法部分。表示我们此次HTTP请求希望执行的操作类型,方法有以下几种定义:
- GET
- POST
- HEAD
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
浏览器通过地址栏访问页面都是GET方法。
表单提交产生POST方法。
HEAD跟GET类似,只返回请求头,多数由JS发起。
PUT和DELETE分别表示添加资源和删除资源。
CONNECT现在多用于HTTPS和WebSocket。
OPTIONS和TRACE一般用于调试,多数线上服务都不支持。
HTTP Status code(状态码)和Status test(状态文本)
常见的状态码:
- 1xx:临时回应,表示客户端请继续。
- 2xx:请求成功。
- 200:请求成功。
- 3xx:表示请求的目标有变化,希望客户端进一步处理。
- 301&302:永久性与临时性跳转。
- 304:跟客户端缓存没有更新(客户端本地已经有缓存的版本,并且Request中告诉了服务端,当服务端通过时间或tag,发现没有更新的时候,就会返回一个不含body的304状态)。
- 4xx:客户端请求错误。
- 403:无权限。
- 404:请求页面不存在。
- 418:It is a teapot.这是一个彩蛋,来自ietf的一个愚人节玩笑(超文本咖啡壶控制协议)
- 5xx:服务端请求错误
- 500:服务端错误。
- 503:服务端暂时性错误,可以一会再试。
HTTP Head(HTTP头)
HTTP头可以看作一个键值对。原则上,HTTP头也是一种数据,可以自由定义HTTP头和值。
说几个重点,先看看Request Header。
Request Header.png再看下Response Header。
Response Header.pngHTTP Request Body
主要用于提交表单场景,常见的body格式:
- application/json
- application/x-www-form-urlencoded(默认采用)
- multipart/form-data(文件上传)
- text/xml
HTTPS
在HTTP协议的基础上,HTTPS和HTTP2规定了更复杂的内容,但是基本保持了HTTP的设计思想,即:使用Request-Response模式。
HTTPS的两个作用:
- 确定请求的目标服务端身份
- 保证传输的数据不会被网络中间节点窃听或者篡改。
HTTPS的标准也是由RFC规定的,详情链接:https://tools.ietf.org/html/rfc2818
HTTPS是使用加密通道来传输HTTP的内容。但是HTTPS首先与服务端建立一条TLS加密通道。TLS构建与TCP协议之上,它实际上是对传输的内容做一次加密,所以从传输内容上看,HTTPS和HTTP没有任何区别。
HTTP2
详情链接:https://tools.ietf.org/html/rfc7540
HTTP2.0最大的改进有两点:
- 支持服务端推送
- 支持TCP链接复用
服务端推送能够在客户端发送第一个请求到服务端时,提前把一部分内容推送给客户端,放入缓存当中,这可以避免客户端请求顺序带来的并行度不高,从而导致的性能问题。
TCP连接复用,则使用同一个TCP连接来传输多个HTTP请求,避免了TCP连接建立时的三次握手开销,和初建TCP连接时传输窗口小的问题。