HTTP简介
超文本传输协议(HyperText Transfer Protocol, HTTP):一种用于分布式、协作式和超媒体信息系统的应用层协议。它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。HTTP是万维网的数据通信的基础。
-
无状态的,无连接
- 每次连接只处理一个请求(HTTP/1.1之后可以处理多个),自身不对请求和响应之间的通信状态进行保存。
-
基于 请求-响应 的模式
- 请求从客户端发出,最后服务器端响应该请求并返回
-
使用可扩展的语义和自描述消息格式
- 可以在协议的基础上添加自己的一些需求,比如头部的字段,带来了很大的灵活性。
-
基于TCP/IP协议的应用层协议
- 使用TCP/IP来作为底层传输保证数据包的可靠性
OSI七层模型
在早期网络发展中,网络设备之间的通信是由生产这些网络设备厂商决定的。每个厂商自己规定怎么封装数据,怎么传输数据。
旧的网络通信方式:自己厂商和自己厂商的设备进行通信。因此,后面才产生了OSI 七层参考模型和TCP/IP 四层/五层模型。这都是一种网络分成模型
在国际化标准组织和厂商共同的协商下,由ISO标准化组织推出了一个参考模型–OSI参考模型。
"开放式系统互联通信参考模型"(英语:Open System Interconnection Reference Model,缩写为 OSI)
它是一种概念模型,ISO 1885,也可以说网络互相模型。
-
它是两台或多台计算机或者系统之间,通信时所用的一套规则和约定。
HTTP协议版本
报文所使用的HTTP版本,格式为:
- HTTP/<major>.<minor>
-
HTTP/0.9
- HTTP的1991原型版本称为 HTTP/0.9。最初版本,功能简陋,只支持GET方法,并且仅能请求访问HTML格式的资源。它很快就被HTTP/1.0取代了。
-
HTTP/1.0
HTTP/1.0添加了版本号、各种HTTP首部、一些额外的方法,以及对多媒体对象的处理。
增加了请求方式POST和HEAD;
请求行必须在尾部添加协议版本字段(http/1.0)才可以使用,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。
除了HTML格式的资源,根据Content-Type可以支持多种数据格式
支持了cache和状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等
每次TCP连接只能发送一个请求(不支持keep-alive)
-
HTTP/1.0+
在20世纪90年代中叶,很多流行的 Web客户端和服务器都在飞快地向HTTP中添加各种特性,以满足快速扩张且在商业上十分成功的万维网的需要。
其中很多特性,包括持久的keep-alive连接(需要声明Connection: keep-alive)、虚拟主机支持,以及代理连接支持都被加入到 HTTP之中,并成为非官方的事实标准。这种非正式的HTTP扩展版本通常称为HTTP/1.0+。
-
HTTP/1.1
重点关注的是校正HTTP设计中的结构性缺陷,明确语义,引人重要的性能优化措施,并删除一些不好的特性。
HTTP/1.1还包含了对20世纪90年代末正在发展中的更复杂的Web应用程序和部署方式的支持。
HTTP/1.1也是当前使用最多最广泛的HTTP版本。
-
默认引入了持久连接(不用声明Connection: keep-alive):一个TCP连接可以允许多个HTTP请求;客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接
- 规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接
加入了管道机制,在同一个TCP连接里,允许多个请求同时发送,增加了并发性
新增了请求方式PUT、PATCH、OPTIONS、DELETE等。
客户端请求的头信息新增了Host字段,用来指定服务器的域名(用于多个虚拟主机共享一个IP)
-
HTTP/2.0(又名HTTP-NG)
-
增加双工模式
即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,而且不用按照顺序一一对应,这样解决了队头堵塞的问题
使用了多路复用的技术同一个连接并发处理多个请求,并发请求的数量比HTTP1.1大了好几个数量级
-
头部信息压缩
- 引入了头信息压缩机制(header compression)。使用gzip或compress压缩后再发送;同时,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,进而提高速度。
-
增加服务器推送的功能,即不经请求服务端主动向客户端发送数据。
当我们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源。
常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。这样省去了客户端重复请求的步骤(建立连接发送请求等步骤)进而提高了速度
-
多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息
对于 HTTP/1.x,即使开启了长连接,请求的发送也是串行发送的,在带宽足够的情况下,对带宽的利用率不够
HTTP/2.0 采用了多路复用的方式,可以并行发送多个请求,提高对带宽的利用率。
-
-
HTTP/3.0
HTTP over QUIC,HTTP3.0的核心是QUIC(读音quick)协议,由Google在 2015年提出的SPDY v3演化而来的新协议
传统的HTTP协议是基于传输层TCP的协议,而QUIC是基于传输层UDP上的协议(可理解为基于UDP的安全可靠的HTTP2.0协议。)
采用UDP,减少了TCP三次握手及TLS握手时间
-
保留了多路复用且解决了线头阻塞问题
- 在之前的多路复用过程中,同一个TCP连接上有多个stream,假如其中一个stream丢包,在重传前后的stream都会受到影响,而QUIC中一个连接上的多个stream之间没有依赖。所以当发生丢包时,只会影响当前的stream,也就避免了线头阻塞问题。
-
解决了TCP的连接迁移问题
- TCP连接基于四元组(源IP、源端口、目的IP、目的端口),切换网络时至少会有一个因素发生变化,导致连接发生变化,QUIC的连接不受四元组的影响,当这四个元素发生变化时,原连接依然维持。QUIC连接不以四元组作为标识,而是使用一个64位的随机数,这个随机数被称为Connection lD,对应每个stream,即使IP或者端口发生变化,只要Connection ID没有变化,那么连接依然可以维持。
-
优化重传机制
- QUIC协议在发送端在传送封包时,初始与重传的每一个封包都改用一个新的编号unique packet number,每一个编号都唯一而且严格递增,这样每次在收到ACK时,就可以依据编号明确的判断这个ACK是来自初始封包或者是重传封包。
HTTP报文格式
HTTP协议请求报文(Request)和响应报文(Response)的结构基本相同都由四部分组成
起始行(strat-line):描述请求或响应的基本信息
请求头字段集合(header):使用key-value 形式描述更详细说明报文
空行(CRLF):请求报文使用空行将请求头和请求数据分隔
-
请求数据/消息正文(message-body):实际传输的数据,除了纯文本还可以是图片、视频等二进制数据
- 消息正文也可能不存在,比如GET请求就不需要entity。
下图为请求报文详细情况
报文所使用的HTTP版本,格式为:HTTP/<major>.<minor>
- majjor:主版本; minor:次要版本
下图为响应报文详细情况
抓包查看下HTTP报文
GET /RapidSSLTLSDVRSAMixedSHA2562020CA-1.crl HTTP/1.1
Cache-Control: max-age = 10800
Connection: Keep-Alive
Accept: */*
If-Modified-Since: Tue, 05 Jul 2022 08:15:24 GMT
If-None-Match: "62c3f31c-6d945"
User-Agent: Microsoft-CryptoAPI/10.0
Host: crl4.digicert.com
HTTP/1.1 304 Not Modified
Accept-Ranges: bytes
Age: 4342
Cache-Control: max-age=10800, public
Date: Wed, 06 Jul 2022 03:33:21 GMT
Etag: "62c3f31c-6d945"
Expires: Wed, 06 Jul 2022 06:33:21 GMT
Last-Modified: Tue, 05 Jul 2022 08:15:24 GMT
Server: ECS (hhp/9AC8)
X-Cache: HIT
ABNF
互联网技术规范通常需要定义正式的语法。BNF(巴科斯-瑙尔范式)的修改版本,称为 Augmented BNF (ABNF),在许多互联网规范中很流行 。当前的规范文档是ABNF。它平衡了紧凑性和简单性与合理的表示能力。标准BNF和ABNF之间的区别涉及命名规则、重复、替代、顺序-独立性和值范围。
规则 | 含义 |
---|---|
CRLF | 互联网标准换行 |
x*y | [x,y]个对应内存,[x: x个或多个] [: 0个或多个] |
() | 括起来是一个整体 |
[] | 括起来表示可有可无 |
/ | 选其中一个 |
HTAB | 横向制表符[ Tab 键] |
SP | 空格 |
DIGIT | 数字(0-9) |
OWS | (SP/HTAB) |
OCTET | 八位数据 |
请求方式
方法 | 包含主体 | 描述 |
---|---|---|
GET | 否 | 通常用于读取操作,请求参数直接拼接在URL后面[有大小限制] |
HEAD | 否 | 与GET方法类似,常用于获取文件大小[没有响应体] |
POST | 是 | 向服务器发送需要处理的数据请求,常用于添加、修改、删除等[没有大小限制] |
PUT | 是 | 将请求的主体部分保存服务器上,通常为发送表单数据 |
DELETE | 否 | 从服务器上删除一份文档 |
CONNECT | 否 | 建立到目标资源标识的服务器的隧道 |
OPTIONS | 否 | 询问可以在服务器上执行哪些方法 |
TRACE | 否 | 对可能经过的代理服务器传到服务器上的报文进行追踪 |
header字段
常见响应状态
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。
HTTP状态码共分为5种类型:
1XX:信息,服务器收到请求,需要请求者继续执行操作
2XX:成功,操作被成功接收并处理
3XX:重定向,需要进一步的操作以完成请求
4XX:客户端错误,请求包含语法错误或无法完成请求
5XX:服务器错误,服务器在处理请求的过程中发生了错误
状态 码 | 状态码英文名称 | 中文描述 |
---|---|---|
100 | Continue | 继续。客户端应继续其请求 |
200 | OK | 请求成功。一般用于GET与POST请求 |
201 | Created | 已创建。成功请求并创建了新的资源 |
202 | Accepted | 已接受。已经接受请求,但未处理完成 |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
301 | Moved Permanently | 永久重定向。请求的资源已被永久的移动到新URI,返回信息会包括新的URI 浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
401 | Unauthorized | 请求要求用户的身份认证 |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 | Bad Gateway | 充当网关或代理的服务器,从远端服务器接收到了一个无效的请求 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
HTTP的请求过程
首先由浏览器应用程序去解析URL的域名
-
根据域名获取对应的IP地址
- 首先从浏览器缓存中寻找解析记录,没有则通过hosts文件(/etc/hosts)寻找,还没有则去DNS服务器中寻找(Localdnsserver、Rootserver域名服务器、国际顶级域名服务商等顺序层层寻找)
chrome://net-internals/#events 可以查看浏览器中的解析缓存
根据IP地址,浏览器发起TCP三次握手
握手建立成功后,开始组装并发送http请求报文,比如 GET http://www.baidu.com/s?wd=a
发送请求头后,发送一个空白行,之后GET请求就结束了,POST请求还会发送body数据
服务器收到请求后,开始解析报文,生成对应的相应数据并发送数据响应头、response header、空白行、body数据
完成后发送四次挥手关闭TCP连接
浏览器收到响应数据后,开始根据数据渲染页面
下面是基于OSI七层模型表示一个HTTP请求的流程