HTTP | 青训营笔记

76 阅读7分钟

超文本传输协议,是一种客户端服务端进行通信的协议。HTTP报文体简单易于理解,并且其设计的头部信息提供了可扩展性,使得新的功能能够轻松的添加进来。HTTP基于TCP协议,是一种有会话但无状态的协议。无状态的意思是请求之间没有关系。

报文

HTTP报文分为请求报文和响应报文,但是两者的结构相似,第一行都是由三元组信息组成,第二行开始是可选的头部信息,然后一个空行表示头部信息结束,之后就是相关的数据。

请求报文

GET / HTTP/1.1
Host: developer.mozilla.org
Accept-Language: fr

请求报文的第一行三元组分别是:请求方法、url和协议版本。

响应报文

HTTP/1.1 301 Moved Permanently
Server: Tengine
Content-Type: text/html

响应报文的三元组分别是:协议版本、状态码和状态说明。

头部信息

HTTP头部信息用于描述报文的一些信息,基本结构是:headerName: data。头部名称是不区分大小写的,值前面的空格会被忽略。

通用头部

  • cache-control:用于实现缓存机制
  • connection:用于选择是否持久化连接,或者升级协议
  • upgrade:提供可选升级协议
  • via:由代理服务器添加,可以用来追踪消息转发情况
  • date:报文创建日期和时间

请求头部

  • accept:表示可接收的内容类型
  • accept-language:表示可理解的自然语言
  • accept-encoding:表示可处理的内容编码方式
  • user-agent:客户端的设备信息
  • host:请求的源信息,主机名+端口号

响应头部

  • server:服务器的一些软件信息
  • accept-ranges:服务器支持请求的范围指定

状态码

1xx

临时性响应,通常用于未处理完的响应。

  • 100:表示接收到客户端的所有内容,客户端需要继续请求
  • 101:切换协议的通知
  • 102:表示服务器正在处理请求,但没有可用的响应

2xx

成功响应的标志

  • 200:最常见的响应状态码
  • 201:PUT请求的目标资源不存在,但是服务器创建了
  • 206:请求成功响应,并且返回了指定区间的资源

3xx

重定向消息

  • 301:表示请求的资源已经永久的移动到另一个URL了
  • 302:表示请求的资源临时移动了
  • 304:资源缓存标志

4xx

客户端出错

  • 401:客户端的身份未通过验证,服务器无法确定客户端的身份
  • 403:客户端没有权限访问,服务器确定客户端的身份
  • 404:访问的资源不存在

5xx

服务端出错

  • 501:服务端无法处理请求方法
  • 503:服务器处于维护状态,暂时无法提供服务

请求方法

  • GET:获取资源,是一个幂等操作,请求报文没有主体部分,把数据都放在url的query中,在url?后,用key=value&&key=value形式携带。响应报文有主体部分,返回请求的资源,这个资源可以被设置缓存。
  • POST:发送数据给服务器,这个方法不是幂等的,相当于创建一条新的记录,通常通过表单的方式发送数据。
  • PUT:同样是发送数据给服务器,但与POST不同,这个操作是幂等的,一般是对数据进行修改,但也有可能会增加数据。如果PUT的目标资源不存在,那么就会创建一份资源,服务器会返回201告诉客户端新建了资源。如果PUT的目标资源存在,则会返回200并对资源进行修改。
  • DELETE:用于删除指定资源。服务端返回202表示会执行操作,但未执行。返回204表示已执行,但无进一步相关信息。返回200表示已执行,并且响应中提供了相关状态的描述信息。
  • OPTIONS:用来获取目的资源所支持的通信选项。CORS中用到。
  • HEAD:返回请求资源的头部信息,仅仅只有头部信息。可以用于判断资源是否要进行下载。

HTTP发展

1.0

1.0默认短连接,在一个HTTP请求结束后就会断开TCP连接,连接无法复用很浪费时间。

1.1

  • 相比1.0的短链接,1.1默认使用长连接,能够在一个TCP连接中进行多个HTTP请求。
  • 1.1添加了range头部,能够指定获取某个部分的资源。
  • 缓存方面:1.0使用last-modified和if-modified-since来作为判断标准。1.1则引入了etag、if-match和if-none-match来进行控制。
  • 1.1增加了host字段,当多个域名共享同一个ip时无法区分每个虚拟主机,因此引入host字段来区分不同的域名

2.0

在讲2.0之前需要讲一下1.0和1.1在性能方面的问题。1.0一个HTTP请求建立一个TCP连接,不用说显而易见的浪费资源。1.1复用TCP连接用于多个HTTP连接,减少了建立TCP连接的时延。有两种模式一种是流水线,HTTP请求必须一个个处理,也就是一个请求-一个响应结束后才能进行下一个HTTP请求。另一种模式是管线化,可以多个HTTP请求并发,但是依然需要按顺序返回响应。这两种模式都会导致队头阻塞的问题,即队列头的请求未处理完就不能处理下一个请求。 2.0引入二进制分帧和数据流的概念,改善了这个问题。

  • 二进制分帧:1.0和1.1的报文都是ASCII码,用户能够理解的形式。而2.0将一个报文处理成一个或多个帧的形式,每个帧带有一些信息来标识这个帧的类型、长度和属于哪个数据流。帧一般可以分为头信息帧和数据帧。
  • 数据流:数据流是一个逻辑通路,在2.0中指的就是一个HTTP请求到响应之间的通路,每个数据流都有唯一的ID,会标识在帧中。根据这个ID就可以将帧组成一个数据流中的报文。
  • 多路复用:有了帧和数据流的概念,就可以实现多路复用。即一条TCP连接可以并发传输多个帧,而帧在传输时是不用按照顺序的,即多个数据流的帧可以并发传输。接收方只要在收到帧后认出它是哪个数据流的就可以。 以上三个设计解决了1.0和1.1中HTTP请求按序处理导致的对头阻塞问题。

2.0另外的特性

  • 头部信息压缩:2.0中客户端和服务端都会维护头部信息表,分为静态表和动态表,静态表中存着一些常用的头部字段,当双方需要发送头部信息的时候直接使用索引号。另外只有在更新头部信息的时候才会传送,如果头部信息没有更新则直接不传输。
  • 服务器推送:服务器会在客户端请求某个资源的时候,推算客户端之后可能会请求的资源,在此时就将那个资源返回给客户端。

3.0

2.0虽然解决了应用层的队头阻塞问题,但还是无法绕过TCP协议的按序收发。也无法避免TCP握手产生的时延,如果再加上SSL/TLS的握手,就至少需要三个RTT才能进行数据传输。

QUIC

Quick UDP Internet Connection:基于UDP的快速网络连接 首先QUIC基础UDP,省去了TCP建立连接三次握手的时延。另外QUIC使用TLS1.3,相比TLS1.1、1.2无需等待TLS握手完成就开始发送应用程序数据的操作,简单来说1.2需要两个RTT才能完成握手,而1.3只需一个RTT。