HTTP通信过程包括从客户端发往服务器端的请求及从服务器端返回客户端的响应。其中HTTP报文作为请求和响应的载体,在其中扮演着邮差的作用。

一、HTTP报文及报文信息

1.1 基础信息

用于HTTP协议交互的信息被称为HTTP报文。
image.png
如上图所示:客户端为请求报文,服务器端为响应报文。报文本身是由多行数据构成的字符串文本(用CR+LF作换行符)。报文包含报文首部,空行,报文主体构成,其中报文主体不必须。
image.png

1.2 结构描述

下面针对各个结构进行描述:
image.png
请求报文和响应报文的首部组成部分:
1、请求行:包含用于请求的方法,请求URI和HTTP版本
2、状态行:包含表明响应结果的状态码,原因短语和HTTP版本
3、首部字段:包含表示请求和响应的各种条件和属性的各类首部,其中首部字段包含:通用首部、请求首部、响应首部和实体首部
4、其他:可能包含HTTP的RFC里未定义的首部,如Cookie

二、HTTP状态码

HTTP状态码负责表示客户端HTTP请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作。
状态码有以下五种类型:
image.png
其中1系列不常用,其他系列只有部分常用。

2.1 2xx成功系列

2xx状态码表示请求成功。
1、200 OK
表示请求被正常处理。
2、204 No Content
表示服务器接收的请求已成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档。一般在只需要客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
3、206 Partial Content
表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。**

2.2 3xx重定向系列

3xx状态码表示浏览器需要执行某些特殊的处理以正常处理请求。
1、301 Moved Permanently
表示资源永久重定向。即该资源已经被分配了新的URI,旧URI不再使用。
2、302 Found
表示临时重定向。表示请求的资源临时分配了新的URI,希望本次去访问新URI。
3、303 See Other
表示由于请求的资源存在着另一个URI,应使用GET方法定向获取请求的资源。303和302功能类似,但是303明确表示客户端应当采取GET方法获取资源,这点与302有区别。
301、302标准是禁止将POST方法改变成GET方法,但实际使用时大家都会这么做。
4、304 Not Modified
表示请求的资源未满足请求条件,不返回新内容,客户端接收到该状态码时,依旧需要使用已缓存的旧资源。
请求条件指请求报文中含有If-Match,If-Modified-Since,If_None-Match,If-Range,If-Unmodified-Since中任一首部。
5、307 Temporary Redirect
临时重定向,和302类似,但是307标准为GET访问。

2.3 4xx客户端错误系列

4xx状态码表示客户端发生了错误。
1、400 Bad Request
表示请求报文中存在语法错误。
2、401 Unauthorized
表示发送的请求需要有认证信息(BASIC认证,DIGEST认证)。若之前发送过一次请求,则表示认证失败。
返回含有401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部用于质询用户信息。
3、403 Forbidden
表示对请求被拒绝。
未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)等情况都可能是403的原因。
4、404 Not Found
表示服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。

2.4 5xx服务器错误系列

5xx状态码表示服务器本身发生错误
1、500 Internal Server Error
表示服务器端在执行请求时发生了错误。也可能是Web应用存在的bug或某些临时的故障。
2、503 Service Unavailable
表示服务器暂时处于超负荷或正在进行停机维护,现在无法处理请求。若事先得知解除以上状况需要的时间,最好写入RetryAfter首部字段再返回给客户端。

三、Web服务器

一台Web服务器可搭建多个独立域名的Web网站,也可以作为通信路径上的中转服务器提升传输效率。

3.1 虚拟主机

一台服务器可以绑定多个域名进行分类服务,这种就属于虚拟主机功能。
互联网上,访问服务的过程是 域名->DNS->IP->服务 。也就是说,请求到达服务器时,已经是IP的形式。所以由于虚拟主机可以寄存多个不同主机名和域名的Web网站,因此在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。

3.2 代理、网关、隧道

1、代理
代理扮演着中间人的角色。它将客户端与服务器端的通信进行转发。
image.png
使用代理服务器的理由有:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的等等。
代理分为缓存代理和透明代理
其中缓存代理预先存储资源副本,当代理接收到该资源请求时,直接返回缓存资源,不再从源服务器中获取资源。
透明代理为:转发请求或响应时,不对报文做任何处理称为透明代理,若处理了报文内容,则为非透明代理。
2、网关
网关是转发其他服务器通信数据的服务器,接收从客户端发来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。
image.png
利用网关可以由HTTP请求转化为其他协议通信。
网关的工作原理与代理类似。但是网关能使通信线路上的服务器提供非HTTP协议服务。由于可以在客户端与网关之间的通信线路上加密,所以利用网关能提高通信的安全性。
3、隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。
image.png
隧道的目的是确保客户端能与服务器进行安全的通信。隧道本身不解析HTTP请求,原样中转给服务器。
4、缓存
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。利用缓存可减少对源服务器的访问,节省通信流量和通信时间。
缓存服务器是代理服务器的一种,并归类在缓存代理类型中。

四、HTTP报文首部

HTTP协议的请求和响应报文中必定包含HTTP首部。
image.png
HTTP请求报文实例:
image.png
HTTP响应报文实例:
image.png
在报文众多字段中,HTTP首部字段包含的信息最为丰富,首部字段同时存在于请求和响应报文中,并涵盖HTTP报文相关的内容信息。

4.1 HTTP首部字段

HTTP首部字段根据用途分为4种类型:
1、通用首部字段
image.png
2、请求首部字段
image.png
3、响应首部字段
image.png
4、实体首部字段
image.png
下面对各个类型的字段进行解析。

4.2 通用首部字段

通用首部字段是指请求报文和响应报文双方都会使用的首部。

4.2.1 Cache-Control 控制缓存的行为

该指令的参数是可选的,多个指令之间通过英文逗号分隔。
image.png
其中,请求时和响应时,Cache-Control有不同的指令参数,或者相同的指令存在不同的意义。
image.png
image.png
下面针对Cache-Control的指令进行解析。

1、表示能否缓存的指令:
1.1 public与private指令
当指定public时,则明确表示其他用户也可以利用缓存。
当指定private时,响应只以特定的用户作为对象,缓存服务器会对该特定用户提供资源缓存服务,对于其他用户发送的请求,缓存服务器则不会返回缓存。
1.2 no-cache指令
image.png
适用no-cache指令的目的是为了防止从缓存中返回过期的资源。
如果在响应中,对no-cache响应指令指定了参数值,那么客户端在接收到这个指定参数值的首部字段对应的响应报文后,就不再使用缓存。如:Cache-Control: no-cache=Location
需要注意的是,no-cache表示不使用过期的缓存资源,no-store才是真正的不进行缓存。

2、控制可执行缓存的对象的指令:
2.1 no-store指令
该指令规定不使用缓存,也不存储缓存。

3、指定缓存期限和认证的指令:
3.1 max-age指令
表示缓存的资源在x秒后失效
image.png
当请求时,指定max-age为0时,缓存服务器需要将请求转发给源服务器。
HTTP1.1中,若缓存服务器遇到同时存在Expires首部字段和max-age指令时,优先处理max-age。HTTP1.0相反。
3.2 s-maxage指令
该指令的功能和max-age相同,不同的是只在代理服务器中生效,如CDN。比如当s-maxage=60时,及时CDN在60秒内更新了资源,浏览器也不会进行请求。
max-age用于普通缓存,而s-maxage用于代理缓存。s-maxage的优先级高于max-age。
3.3 min-fresh指令
min-fresh表示可接受至少还未过x秒内的缓存资源。
image.png
如上图,当指定min-fresh为60秒时,过了60秒的资源都无法返回。
3.4 max-stale指令**
该指令表示能容忍的最大过期时间,单位为秒。当未指定max-stale指令的秒数值时,那么表示客户端接受任何时间的缓存;若指定了max-stale的值,则表示可接受规定时间内过期的缓存。

通过Cache-Control不同的指令组合,可以实现不同的缓存策略。
image.png

4.2.2 Connection 控制转发与管理连接

Connection首部字段具备两个作用
1、控制不再转发给代理的首部字段
image.png
在客户端发送请求和服务器端返回响应时,使用该字段可控制不再转发给代理的首部字段。
2、管理持久连接
HTTP1.1版本的默认连接都是持久连接。客户端会在持久连接上连续发送请求(Connection: Keep-Alive)。当服务器端想明确断开连接时,则指定Connection首部字段值为Close。

4.2.3 Date

Date表明创建HTTP报文的日期和时间。
image.png

4.2.4 Trailer

该字段会事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在HTTP1.1版本分块传输编码时。
image.png
如上,指定Trailer的值为Expires,在报文主体后(分块长度为0之后)出现了首部字段Expires。

4.2.5 Transfer-Encoding

该字段规定了传输报文主体时采用的编码方式。在HTTP1.1的传输编码方式仅对分块传输编码有效。
image.png
上图中,Transfer-Encoding指定分块传输。分为3312字节和914字节大小的分块数据。

4.2.6 Upgrade

该字段用于检测HTTP协议及其他协议是否可使用更高的版本进行通信。
image.png
如上图,Upgrade首部字段指定的值TLS/1.0产生作用的对象仅限于客户端和近邻服务器之间,因此,使用该字段时,还需要额外指定Connection: Upgrade。
对于附有首部字段Upgrade的请求,服务器可用101 Switching Protocols状态码作为响应返回。

4.2.7 Via

使用Via是为了追踪客户端与服务器之间的请求和响应报文的传输路径。
image.png
image.png

4.3 请求首部字段

请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。

4.3.1 Accept

Accept首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级(q)。若值为星号(*)则表示任意编码格式都支持。
image.png
其中媒体类型大致有:

  • 文本文件

text/html,html格式
text/plain,纯文本格式
text/css,
application/xhtml+xml,xhtml格式
application/json,json数据格式

  • 图片文件

image/jpeg,
image/gif,
image/png

  • 视频文件

video/mpeg,
video/quicktime

  • 二进制文件

application/octet-stream,二进制流数据,如常见的文件下载

  • 其他

applocation/x-www-urlencoded,form表单默认的提交数据的格式k-v
multipart/form-data,表单文件上传

4.3.2 Accept-Charset

该字段用来通知服务器,客户端支持的字符集及字符集的相对有限顺序(q)。
该字段应用于内容协商机制的服务器驱动协商。image.png

4.3.3 Accept-Encoding

该字段用来告知服务器,客户端支持的内容编码及内容编码的优先级顺序(q)。
image.png
其中编码参数有:

  • gzip

由gzip(GNU zip)程序压缩生成的编码格式。

  • compress

由UNIX文件压缩程序compress生成的编码格式。

  • deflate

组合使用zlib格式及deflate压缩算法生成的编码格式。

  • identity

无压缩原格式。

4.3.4 Accept-Language

该字段用来告知服务器,客户端能够处理的自然语言集,以及自然语言的优先级(q)
image.png

4.3.5 Authorization

该字段用来告知服务器,客户端的认证信息。
image.png

4.3.6 Host

首部字段Host会告知服务器,请求的资源所处的主机名和端口号。

4.3.7 If-Match

对于形如If-xxx这种样式的请求首部字段,都称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
If-Match首部字段告知服务器匹配资源所用的实体标记值(ETag)。
服务器会对比该字段值和资源的ETag值,仅当两者一致时,才会执行请求。反之,返回状态码412 Precondition Failed的响应。
也可以使用通配符星号(*)作为字段值,届时服务器将会忽略ETag值,只有资源存在就处理请求。
image.png

4.3.8 If-Modified-Since

该字段告知服务器,若资源在字段值时间之后更新了,则处理请求;若资源在字段值时间之后未更新过,则返回304 Not Modified的响应。
image.png

4.3.9 If-None-Match

该字段和If_Match作用相反。
在GET或HEAD方法中使用该字段可获取最新的资源。因此,这与使用首部字段If-Modified-Since时有些类似。
image.png

4.3.10 If-Range

该字段和Range字段组合使用,告知服务器,若指定的If-Range值(ETag值或者时间)和请求资源的ETag值或时间一致时,则作为范围请求处理。反之,则返回全体资源。
image.png

4.3.11 Max-Forwards

该字段值为十进制整数,表示可经过的服务器最大数目。
image.png

4.3.12 Referer

该字段告知服务器请求的原始资源的URI。
image.png

4.3.13 User-Agent

User-Agent用于传达浏览器的种类。

4.4 响应首部字段

响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息、以及对客户端的附加要求等信息。

4.4.1 Accept-Ranges

该字段用来告知客户端,服务器是否能处理范围请求。
image.png
可指定的字段值有两种:
1、bytes,可以处理范围请求
2、none,不可处理范围请求

4.4.2 Age

该字段告知客户端,源服务器在多久前创建了响应,字段值单位为秒。
image.png

4.4.3 ETag

该字段告知客户端资源实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag值。
image.png
ETag分为强Etag和弱ETag:
强ETag:无论资源发生多么细微的变化都会改变其值。
弱ETag:只用于提示资源是否相同。只有资源发生了根本性改变,产生差异时才会改变ETag值。此时,会在字段值最开始处附加 “W/” 。
image.png

4.4.4 Location

使用该字段可将客户端引导至某个与请求URI位置不同的资源。
image.png

4.4.5 Retry-After

该字段告知客户端应该在多久之后再次发送请求。主要配合状态码503 Service Unavailable响应或3xx 重定向响应一起使用。字段值可以为具体的时间或秒数。

4.4.6 Server

该字段告知客户端当前HTTP服务器应用程序的信息。
image.png

4.4.7 Vary

当代理服务器接收到带有Vary首部字段指定获取资源的请求时,如果使用的Accept-Language字段的值相同,那么就直接从缓存返回响应。反之,则需要先从源服务器端获取资源后才能作为响应返回。
image.png
注意,此处Vary的值不一定是Accep-Language。
即使对相同资源发起请求,但由于Vary指定的首部字段不相同,因此必须要从源服务器重新获取资源。

4.4.8 WWW-Authenticate

该字段在401 Unauthorized响应中,是必带的。它会告知客户端需要的认证授权信息。
image.png

4.5 实体首部字段

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。

4.5.1 Allow

该字段用于通知客户端能够支持的Request-URI指定资源的所有HTTP方法。当服务器接收到不支持的HTTP方法时,会以状态码405 Method Not Allowed 作为响应返回。同时会返回支持的HTTP方法。

4.5.2 Content-Encoding

该字段告知客户端服务器对实体的主体部分选用的内容编码方式。

4.5.3 Content-Language

该字段告知客户端,实体主体部分使用的自然语言

4.5.4 Content-Length

该字段表明了实体主体部分的大小,单位为字节。
值得注意的是,对实体主体部分进行编码传输时,不能再使用该字段标注大小。

4.5.5 Content-Location

该字段给出与报文主体部分相对应的URI。如使用Accept-Language的服务器驱动型请求,当返回的页面内容与实际请求的对象不同时,首部字段Content-Location会写明URI。即假如访问的是www.baidu.com,返回的对象却是www.baidu.com/index.html。

4.5.6 Content-Range

针对范围请求,返回响应时使用该字段告知客户端返回的部分内容信息。字段值以字节作为单位,表示当前发送部分及整个实体大小。
image.png

4.5.7 Content-Type

该字段说明了实体主体部分对象的媒体类型。和首部字段Accept的参数一致。
image.png

4.5.8 Expires

该字段表明缓存过期时间,为具体的时间值,一般和Last-Modified一起使用。该字段的局限性在于,修改了本地时间,会造成缓存失效。
image.png
Cache-Control在指定了max-age时,会优先处理max-age。

4.5.9 Last-Modified

该字段表明资源最终修改时间。
image.png

4.6 其他首部字段

4.6.1 Cookie相关首部字段

1、Set-Cookie
Set-Cookie表示服务器端设置的Cookie信息。
image.png
image.png
2、Cookie
该字段值是客户端从服务器端获取到的cookie信息。

4.6.2 X-Frame-Options

该字段属于HTTP响应首部,用于控制网站内容在其他web网站的Frame标签内的显示问题。主要目的是问了防止点击劫持(clickjacking)攻击。
image.png
有两个可指定的字段值:

  • DENY:拒绝
  • SAMEORIGIN:仅同源域名下的页面匹配时许可。

    4.6.3 X-XSS-Protection

    该字段属于HTTP响应首部,是针对XSS的一种对策。
    image.png
    有两个可指定的字段值:

  • 0:不启用

  • 1:启用xss过滤

    4.6.4 DNT

    该字段属于HTTP请求首部,DNT全称为Do Not Track,意为拒绝个人信息收集,是表示拒绝被精准广告追踪的一种方式。
    有两个可指定的字段值:

  • 0:允许被追踪

  • 1:拒绝被追踪

    4.6.5 P3P

    该字段属于HTTP响应首部,通过利用P3P(在线隐私偏好平台)技术,可以让web网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。
    image.png

    五、最后

    以上为HTTP报文的解析。分别描述了HTTP报文结构,HTTP状态码,Web服务器以及HTTP报文字段信息。

参考书籍:《图解HTTP》