HTTP协议详解
实际上,对浏览器的实现者来说,他们做的事情,就是把一个URL变成一个屏幕上显示的网页。
这个过程是这样的:
- 浏览器首先使用HTTP协议或者HTTPS协议,向服务端请求页面;
- 把请求回来的HTML代码经过解析,构建成DOM树;
- 计算DOM树上的CSS属性;
- 最后根据CSS属性对元素逐个进行渲染,得到内存中的位图;
- 一个可选的步骤是对位图进行合成,这会极大地增加后续绘制的速度;
- 合成之后,再绘制到界面上。
从HTTP请求回来,就产生了流式的数据,后续的DOM树构建、CSS计算、渲染、合成、绘制,都是尽可能地流式处理前一步的产出:即不需要等到上一步骤完全结束,就开始处理上一步的输出,这样我们在浏览网页时,才会看到逐步出现的页面。
HTTP请求
1 2 |
GET / HTTP/1.1 Host: time.geekbang.org |
HTTP响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
HTTP/1.1 301 Moved Permanently Date: Fri, 25 Jan 2019 13:28:12 GMT Content-Type: text/html Content-Length: 182 Connection: keep-alive Location: https://time.geekbang.org/ Strict-Transport-Security: max-age=15768000 <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>openresty</center> </body> </html> |
在请求部分,第一行被称作 request line,它分为三个部分,HTTP Method,也就是请求的“方法”,请求的路径和请求的协议和版本。
在响应部分,第一行被称作 response line,它也分为三个部分,协议和版本、状态码和状态文本。
紧随在request line或者response line之后,是请求头/响应头,这些头由若干行组成,每行是用冒号分隔的名称和值。
在头之后,以一个空行(两个换行符)为分隔,是请求体/响应体,请求体可能包含文件或者表单数据,响应体则是html代码。
HTTP协议
path是请求的路径完全由服务端来定义,没有很多的特别内容;而version几乎都是固定字符串;response body是我们最熟悉的HTML
HTTP Method(方法)
我们首先来介绍一下request line里面的方法部分。这里的方法跟我们编程中的方法意义类似,表示我们此次HTTP请求希望执行的操作类型。方法有以下几种定义:
- GET
- POST
- HEAD
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
浏览器通过地址栏访问页面都是GET方法。表单提交产生POST方法。
HEAD则是跟GET类似,只返回请求头,多数由JavaScript发起
PUT和DELETE分别表示添加资源和删除资源,但是实际上这只是语义上的一种约定,并没有强约束。
CONNECT现在多用于HTTPS和WebSocket。
OPTIONS和TRACE一般用于调试,多数线上服务都不支持。
HTTP Status code(状态码)
接下来我们看看response line的状态码和状态文本。常见的状态码有以下几种。
- 1xx:临时回应,表示客户端请继续。
- 2xx:请求成功。
-
- 200:请求成功。
- 3xx: 表示请求的目标有变化,希望客户端进一步处理。
-
- 301&302:永久性与临时性跳转。
- 304:跟客户端缓存没有更新。
- 4xx:客户端请求错误。
-
- 403:无权限。
- 404:表示请求的页面不存在。
- 5xx:服务端请求错误。
-
- 500:服务端错误。
- 503:服务端暂时性错误,可以一会再试。
HTTP Head (HTTP头)
HTTP头可以看作一个键值对。原则上,HTTP头也是一种数据,我们可以自由定义HTTP头和值。不过在HTTP规范中,规定了一些特殊的HTTP头,我们现在就来了解一下它们。
Request Header:
Response Header:
HTTP Request Body
HTTP请求的body主要用于提交表单场景。实际上,http请求的body是比较自由的,只要浏览器端发送的body服务端认可就可以了。一些常见的body格式是:
- application/json
- application/x-www-form-urlencoded
- multipart/form-data
- text/xml
我们使用html的form标签提交产生的html请求,默认会产生 application/x-www-form-urlencoded 的数据格式,当有文件上传时,则会使用multipart/form-data。
HTTPS
在HTTP协议的基础上,HTTPS和HTTP2规定了更复杂的内容,但是它基本保持了HTTP的设计思想,即:使用上的Request-Response模式。
我们首先来了解下HTTPS。HTTPS有两个作用,一是确定请求的目标服务端身份,而是保证传输的数据不会被网络中间节点窃听或者篡改。
HTTPS的标准也是由RFC规定的,你可以查看它的详情链接:
https://tools.ietf.org/html/rfc2818
HTTPS是使用加密通道来传输HTTP的内容。但是HTTPS首先与服务端建立一条TLS加密通道。TLS构建于TCP协议之上,它实际上是对传输的内容做一次加密,所以从传输内容上看,HTTPS跟HTTP没有任何区别。
HTTP2
HTTP2是HTTP1.1的升级版本,你可以查看它的详情链接。
https://tools.ietf.org/html/rfc7540
HTTP2.0 最大的改进有两点,一是支持服务端推送、二是支持TCP连接复用。
服务端推送能够在客户端发送第一个请求到服务端时,提前把一部分内容推送给客户端,放入缓存当中,这可以避免客户端请求顺序带来的并行度不高,从而导致的性能问题。
TCP连接复用,则使用同一个TCP连接来传输多个HTTP请求,避免了TCP连接建立时的三次握手开销,和初建TCP连接时传输窗口小的问题。
Note: 其实很多优化涉及更下层的协议。IP层的分包情况,和物理层的建连时间是需要被考虑的。