HTTP 的两个最重要的点:
- 基于请求/响应
- 无状态
HTTP请求的整个流程:
DNS域名解析 (域名–>IP地址)
- 在浏览器 DNS 缓存中搜索
对于 Chrome 浏览器:chrome://net-internals/#dns
- 在操作系统 DNS 缓存中搜索
- 读取系统 hosts 文件,查找其中是否有对应的 ip
我觉得系统 DNS 缓存本身就是 hosts 文件的一份拷贝,毕竟不能每次都去hosts 文件中进行查找。至于是不是,那只能去看系统实现了。
ipconfig /displaydns 显示 DNS 解析程序缓存的内容。
- 向本地配置的首选 DNS 服务器发起域名解析请求
建立TCP连接
为了准确地传输数据,TCP协议采用了三次握手策略。发送端首先发送一个带SYN(synchronize)标志的数据包给接收方,接收方收到后,回传一个带有SYN/ACK(acknowledegment)标志的数据包以示传达确认信息。最后发送方再回传一个带ACK标志的数据包,代表握手结束。在这过程中若出现问题中断,TCP会再次发送相同的数据包。
TCP是一个端到端的可靠的面向连接的协议,所以HTTP基于传输层TCP协议不用担心数据的传输的各种问题。
一个描述TCP三次握手的例子:
敌人封锁江面, 我方间谍和联络员只能通过电报机隔着江面交流. 但是那时的电报机质量不稳定, 有可能会出现失灵的情况. 所以就出现了如下对话:
间谍: 联络员, 你能收到我发的话么? 你要是能收到, 就说明我这个电报机可以发电报.
联络员: 间谍, 我收到你发的话了, 这说明我的电报机可以收. 但是我不确定我的电报机能不能发, 你能收到我发的这句话么? 你要是能收到, 就说明我的电报机是可以发电报的.
间谍: 联络员, 我收到你的话了. 我的电报机也是能发能收, 我们可以正式交流情报了.
三次握手的目的就是确保客户端和服务端能够互相接收到对方发送的数据。
发起 HTTP 请求
一个 HTTP 请求包括:
- 请求命令(如:
GET/sample/hello.jsp HTTP/1.1
) - 请求头(描述自身的一些信息)
- 请求体(对于GET方式可有可无)
请求头与请求体之间需要有一个空白行做分隔。
请求方法:
- GET:获取资源
- POST:传输实体
- HEAD:获取报文首部
- PUT:传输文件
- DELETE:删除文件
- OPTIONS:询问支持的方法
- TRACE:追踪路径
请求报文:
接受响应结果
服务器应答包括:
- 响应状态(如:
HTTP/1.1 200 OK
) - 响应头(描述数据的相关信息)
- 响应体
状态码:
- 1**:信息性状态码
- 2**:成功状态码
- 200:OK 请求正常处理
- 204:No Content请求处理成功,但没有资源可返回
- 206:Partial Content对资源的某一部分的请求
- 3**:重定向状态码
- 301:Moved Permanently 永久重定向
- 302:Found 临时性重定向
- 304:Not Modified 缓存中读取
- 4**:客户端错误状态码
- 400:Bad Request 请求报文中存在语法错误
- 401:Unauthorized需要有通过Http认证的认证信息
- 403:Forbidden访问被拒绝
- 404:Not Found无法找到请求资源
- 5**:服务器错误状态码
- 500:Internal Server Error 服务器端在执行时发生错误
- 503:Service Unavailable 服务器处于超负载或者正在进行停机维护
响应报文:
一般情况下, 一旦 Web 服务器向浏览器发送了响应数据, 它就要关闭此次 TCP 连接.。如果浏览器或者服务器在其头信息加入了这行代码
Connection:keep-alive
TCP 连接在发送后将仍然保持打开状态。于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间, 还节约了网络带宽。
浏览器解析 HTML
浏览器按顺序解析HTML文件,构建DOM树。准确地说,浏览器需要加载解析的不仅仅是HTML,还包括CSS、JS以及图片、视频等其他媒体资源。
浏览器通过解析HTML,生成DOM树,解析CSS,生成CSS规则树,然后通过DOM树和CSS规则树生成渲染树。渲染树与DOM树不同,渲染树中并没有head、display为none等不必显示的节点。
要注意的是,浏览器的解析过程并非是串连进行的,比如在解析CSS的同时,可以继续加载解析HTML,但在解析执行JS脚本时,会停止解析后续HTML。
为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。
浏览器布局渲染
关闭TCP连接
为了避免服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方都可以发起关闭请求。与创建TCP连接的3次握手类似,关闭TCP连接,需要4次握手。
上图可以这么理解:
客户端:“兄弟,我这边没数据要传了,咱关闭连接吧。”
服务端:“收到,我看看我这边有木有数据了。”
服务端:“兄弟,我这边也没数据要传你了,咱可以关闭连接了。”
客户端:“好嘞。”
使用 Fiddler 模拟一次请求
参考:
http://android.jobbole.com/85218/
https://www.jianshu.com/p/c1d6a294d3c0