http:
MDN
HTTP 是基于 TCP/IP
协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。
每个版本
http 0.9 (1991 已弃)
- 只有get请求 服务器只能回应HTML格式的字符串,
- 服务器发送完毕,就关闭TCP连接。
http 1.0:(1996-05 略)
- 任何格式的内容都可以发送。
- 还引入了post命令和head命令
- 除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。
- 其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。
标准请求:
GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
一个包含图片的页面
<IMG SRC="/myimage.gif">
</HTML>
回应:
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html>
<body>Hello World</body>
</html>
缺点:
HTTP/1.0 版的主要缺点是,每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。
TCP连接的新建成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start)。
所以,HTTP 1.0版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了
用Connection: keep-alive解决
http 1.1(1997)
- 持久连接:连接可以复用,节省了多次打开TCP连接加载网页文档资源的时间。
客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。
不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。
- 增加管线化技术,允许在第一个应答被完全发送之前就发送第二个请求,以降低通信延迟。 支持响应分块。 引入额外的缓存控制机制。
即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。
即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。
- 分块传输编码 需要Content-Length
- 引入内容协商机制,包括语言,编码,类型等,并允许客户端和服务器之间约定以最合适的内容进行交换。
- 增加Host头,用来指定服务器的域名,能够使不同域名配置在同一个IP地址的服务器上。
- 新增PUT、PATCH、HEAD、 OPTIONS、DELETE
缺点:
虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为"队头堵塞"(Head-of-line
blocking)。
http 2:(2015,下一版本是http3了)
基础:
2009年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。
新增:
- 二进制协议:HTTP/2是二进制协议而不是文本协议。不再可读,也不可无障碍的手动创建,改善的优化技术现在可被实施。
HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。
- 多工(双向实时通信) 这是一个复用协议。并行的请求能在同一个链接中处理,移除了HTTP/1.x中顺序和阻塞的约束。
HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了"队头堵塞"。
- 头信息压缩 :压缩了headers。因为headers在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
头信息使用gzip或compress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
- 服务器推送:其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求
2016
对Alt-Svc的支持允许了给定资源的位置和资源鉴定,允许了更智能的CDN缓冲机制。
Client-Hints的引入允许浏览器或者客户端来主动交流它的需求,或者是硬件约束的信息给服务端。
Client-Hints :这个大佬描述是这样的:浏览器在页面发起子资源请求时,会通过新增的一系列头部字段带上分辨率、设备像素比、图片宽度等信息,使得各种复杂的策略可以挪到服务端去实现了。
http 消息:
HTTP 请求和响应具有相似的结构,由以下部分组成︰
请求:请求行(request line)、请求头部(header)、空行、请求数据
响应:状态行、消息报头、空行和响应正文
以下为节选MDN的描述
- 一行起始行用于描述要执行的请求,或者是对应的状态,成功或失败。这个起始行总是单行的。
- 一个可选的HTTP头集合指明请求或描述消息正文。
- 一个空行指示所有关于请求的元数据已经发送完毕。 一个可选的包含请求相关数据的正文 (比如HTML表单内容), 或者响应相关的文档。
- 正文的大小有起始行的HTTP头来指定。
起始行:
request | response |
---|---|
请求行 | 状态行 |
GET /hello.txt HTTP/1.1 | HTTP/1.1 200 OK |
一个 HTTP 方法 ,请求目标,HTTP 版本 (HTTP version) | 协议版本,状态码 ,状态文本 |
header
不区分大小写的字符串,紧跟着的冒号 (’:’) 和一个结构取决于 header 的值。 整个 header(包括值)由一行组成,这一行可以相当长。
有许多请求头可用,它们可以分为几组:
- General headers,例如 Via,适用于整个报文。
- Request headers,例如. User-Agent,Accept-Type,通过进一步的定义(例如 Accept-Language),或者给定上下文(例如Referer),或者进行有条件的限制 (例如 If-None) 来修改请求
- Entity headers,例如Content-Length,适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。
消息报头:
- General headers,例如 Via,适用于整个报文。
- Response headers,例如 Vary 和 Accept-Ranges,提供其它不符合状态行的关于服务器的信息。
- Entity headers,例如 Content-Length,适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。
request-Body:
请求的最后一部分是它的 body。不是所有的请求都有一个 body:例如获取资源的请求,GET,HEAD,DELETE 和 OPTIONS,通常它们不需要 body。 有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含 HTML 表单数据)。
Body 大致可分为两类:
- Single-resource bodies,由一个单文件组成。该类型 body 由两个 header 定义: Content-Type 和Content-Length。
- Multiple-resource bodies,由多部分 body组成,每一部分包含不同的信息位。通常是和 HTML Forms 连系在一起。
response-body:
响应的最后一部分是 body。不是所有的响应都有 body:具有状态码 (如 201 或 204) 的响应,通常不会有 body。
Body 大致可分为三类:
- Single-resource bodies,由已知长度的单个文件组成。该类型 body 由两个 header 定义:Content-Type 和 Content-Length。
- Single-resource bodies,由未知长度的单个文件组成,通过将 Transfer-Encoding 设置为 chunked 来使用 chunks 编码。
- Multiple-resource bodies,由多部分 body 组成,每部分包含不同的信息段。但这是比较少见的。
下一篇:http常用http头,以及https