HTTP 概览
HTTP(HyperText Transfer Protocol,超文本传输协议)是WWW数据交换的基础,制定了浏览器和服务器之间的通讯规则。
本文主要介绍HTTP协议的发展历程,在每个版本中的特点及原因。
HTTP协议主要有四个版本:0.9、1.0、1.1、2。
HTTP/0.9
在1996年正式公布HTTP/1.0
之前,HTTP并没有建立标准,这期间的协议被称为HTTP/0.9
。
HTTP/0.9功能极为简单,Request只有一行且只有一个GET命令,命令后面跟着的是资源路径。
GET /index.html
Reponse同样简单,仅包含文件内容本身。
<html>
<body>HELLO WORLD!</body>
</html>
仅能发送HTML文件,发生错误时,返回包含错误的HTML文件。
但此时HTTP协议就具有 无状态性,请求独立,请求结束后释放当前连接。
HTTP/1.0
在1996年,HTTP/1.0发布。新增了以下功能:
- 在每个request的GET一行后面添加版本号,
GET /index.html HTTP/1.0
; - 在response中添加状态行并作为第一行返回给用户,
200 OK
; - 在request和response中添加header的概念;
- 在header中添加content-type,以此可以传输html之外类型的文件;
- 在header中添加content-encoding来支持不同编码格式文件的传输;
- 引入了POST和HEAD命令,丰富了浏览器与服务器的交互方式;
- 支持长连接(默认还是短连接);
此外,在HTTP/1.0中规定header信息必须是ASCII
码,后面的数据可以是通过Content-Type
指定格式,还可以在Content-Type中添加参数,如Content-Type: text/html; charset=utf-8
。
HTTP/1.1
HTTP/1.1是目前使用最为广泛的HTTP版本。主要新增以下几个功能:
- 默认长连接机制,
Connection: keep-alive
; - Pipeline机制;
- header中引入host;
- Chunked编码传输;
- 更全面的Cache机制;
- 引入OPTIONS, PUT, DELETE, TRACE和CONNECT方法;
Pipeline机制
pipeline机制是在一条connection上多个http request不需要等待response就可以连续发送的技术。
在理想情况下,所有资源的获取仅仅需要一个RTT时长,这看上去是非常大的优化和诱惑,但为何主流浏览器上默认下该功能都是关闭状态呢?答案只有一个:队头阻塞。
关于pipeline还需要注意的是:
1)只有幂等的方法才能使用pipeline,例如GET和HEAD请求。
2)新建立的连接由于无法得知服务端是否支持HTTP/1.1,因此也不能使用pipeline,即只能重用之前的连接时才能使用pipeline。
并行连接
通过在浏览器端同时开启多个http connection
的方式从服务端获取数据资源以提升访问速度。
每个并行连接的建立过程都会完成一次完整的DNS解析和TCP握手过程。
在Chrome中设置了每一个域名最多同时可以对应 六条 连接。
host头域
在请求头域中新增了Host字段,其用来指定服务器的域名。
有了Host字段,在同一台服务器上就可以搭建不同的网站了,这也为后来虚拟化的发展打下了基础。
Cache机制
Cache 不仅有利于提高用户访问效率,还可以节省客户端和服务端宽带资源。
Cache 要解决的问题包括:
1)判断哪些资源可以被Cache及访问策略;
2)判断Cache是否过期;
3)向服务端发起问询,查看已过期的Cache资源是否在服务端发生了变化;
名称 | 首部字段 | 作用 |
---|---|---|
Cache-Control | 通用首部字段 | Cache机制最主要策略;用来解决问题1和问题2 |
Pragma | 通用首部字段 | HTTP/1.0产物;目前仅用在请求首部;用来解决问题2 |
Expires | 响应首部字段 | 标注资源过期时间;用来解决问题2 |
Last-Modified | 响应首部字段 | 表明资源最终修改时间;用来解决问题2; 与If-Modifed-Since配合解决问题3 |
Etag | 响应首部字段 | 将资源以字符串形式做唯一标识; 与If-None-Match配合解决问题3 |
If-Modifed-Since | 请求首部字段 | 向server端问询资源是否发生变化; 与Last-Modified配合解决问题3 |
If-None-Match | 请求首部字段 | 向server端问询资源是否发生变化; 与Etag配合解决问题3 |
Chunked机制
用户通常会通过response header中返回的Content-Length
来判断服务端返回数据的大小。
但随着网络技术的不断发展,越来越多的动态资源被引入进来,这时服务端就无法在传输之前知道待传递资源的大小,也就无法通过Content-Length来告知用户资源大小。
服务器可以一边动态产生资源,一边传递给用户,这种机制称为“分块传输编码”(Chunkded Transfer Encoding),它是在HTTP/1.1中引入的,允许服务端发送给客户端的数据分为多个部分,此时服务器端需要在header中添加Transfer-Encoding: chunked
头域来替代传统的Content-Length
。
因此,当你在response header中没有找到对应的Content-Length的时候,该header中一定会包含“Transfer-Encoding: chunked”。
数据压缩
Http数据部分的压缩其实是就是对其编码的过程(例如gzip)。