HTTP 概览
5 min read

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)。