本文是作者原创文章,欢迎转载,请注明出处 from:@Eric_Lai

reference: 《图解HTTP》(日) 上野宣

HTTP协议,中文名称为超文本传输协议(HyperText Transfer Protocol),是互联网上应用最为广泛的一种网络协议。在TCP/IP协议族中,普遍认为HTTP协议位于最上层,即第七层(应用层)。因为其位于应用层,所以HTTP协议不涉及数据包(packet)传递,其主要的作用是规定网络上两台需要通信的计算机(即服务器和客户端)的通信格式,HTTP协议默认使用80端口(如果没有明文指明其他端口,但是80端口出于安全原因操作系统通常会默认禁止用户自己的程序使用)。

TCP/IP协议族的层级划分图

ps:上图来自维基百科

HTTP发展到今天一共出现了以下几个版本(按照时间出现先后排序):

准备知识

网络通信流程

如果不像文中一开始的图那么精细的划分网络协议层,我们可以将其粗略地划分为四层:

  1. 应用层,决定向用户提供应用服务时通信的活动;
  2. 传输层,提供处于网络连接中两台计算机的数据传输,著名的TCP/UDP协议都在这一层;
  3. 网络层,处理流动的网络数据包,规定数据包经什么路径从出发点到达目的地;
  4. 链路层,处理网络连接相关硬件工作;

当一个HTTP请求被发起时,应用层把数据交给传输层,传输层收到数据后将数据分割打上标记序号和端口号后将数据交给网络层,网络层增加通信目的地的MAC地址后发给链路层,链路层将其发送出去;同理,服务端接收到数据后,逐层向上传递,解除每一层的部首信息,将报文拼接成原始的样子后进行处理。 网络数据通信过程

ps:上图来自《图解HTTP》(日)上野宣

与HTTP关系密切的协议

在TCP/IP协议族当中,有3个协议与HTTP有非常密切的关系:

简单的HTTP协议

Note:下文主要基于HTTP/1.1进行叙述

首先明确以下三点基础知识:

一个示例请求可以如下:

访问百度主页的HTTP请求实例

一个示例响应可以如下:

请求百度主页的响应

ps:在chrome或者Firefox等现代浏览器上,可以使用开发者工具查看这些信息。

HTTP方法

在HTTP/1.1当中,提供了若干种不同的方法对应不同的需求,下面简要介绍一下(重点需要了解GET和POST方法,其他比较少用):

Cookie技术

HTTP是无状态协议,也就是说它不对之前的请求和响应进行管理,即无法根据之前的状态对本次请求进行处理。假设一个需要登录的网站,在这种情况下,每次刷新页面都得重新登录。但是实际我们并不需要这么做,这就得益于Cookie技术了:

cookie工作示意图

ps:上图来自《图解HTTP》(日) 上野宣

HTTP报文内的HTTP信息

用于HTTP协议交互的信息被称为HTTP报文。客户端的HTTP报文叫做请求报文,服务器的HTTP报文叫做响应报文。HTTP报文是由多行数据构成的字符串文本(用CR+LF(\r\n,回车换行符)表示换行),报文大致可以分为:报文部首(必须有的)、报文主体(不一定非要有)。

理解报文主体和实体主体,首先明确以下两个概念:

HTTP报文主体用于传输请求或者响应的实体主体。通常,报文主体和实体主体是一样的,只有当在传输过程中进行了编码操作(编码可以提升传输速率,但是需要消耗CPU资源)时,实体主体的内容会发生变化,从而导致这两者不一样。

状态码

相信大部分人在使用web的时候都遇到过著名的“404”页面,404就是一个HTTP状态码。对于程序员来说,相信大部分人喜欢200多过404了。

HTTP状态码的类别如下:

状态码类别原因短语
1XX信息状态码(informational)接收到的请求正在处理
2XX成功状态码(Success)请求正常处理完毕
3XX重定向状态码(Redirection)需要进行附加的操作完成请求
4XX客户端错误状态码(Client Error)服务器无法处理请求
5XX服务器错误状态码(Server Error)服务器处理请求出错

如需要查看详细的状态码,维基百科传送门,MDN社区传送门

HTTP首部

HTTP报文部

一个完整的HTTP报文应该有以下结构:

  1. (HTTP)报文首部;
  2. 空行(CR + LF);
  3. (HTTP)报文主体;

HTTP报文首部由几个字段组成,分别是:请求行(状态行)、请求(响应)首部字段、通用首部字段、实体首部字段和其他。其中,以”首部字段“四字结尾的几个字段合称为HTTP首部字段。

HTTP首部字段

HTTP 首部字段是构成 HTTP 报文的要素之一。在客户端与服务器之间以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。

摘自:《图解HTTP》 — 〔日〕上野宣

首部字段的结构如下所示:

首部字段名称:字段值
// example
Content-Type: text/html
Keep-Alive: timeout=15, max=100

如果一个HTTP报文当中含有两个名字一样但是字段值不相同的首部字段,根据不同的浏览器可能会出现不同的结果,需要谨慎注意。

上文也提到了,首部字段总共分为四类:

HTTP协议具体的字段列表,可以参见维基百科传送门

为Cookie服务的首部字段

由于HTTP协议是无状态协议,在实际的开发中,往往我们又需要保存用户的状态信息。这时候就要用到Cookie,所以单独列一小节探究一下与其相关的首部字段。主要就是以下两个字段:

首部字段名说明首部类型
Set-Cookie开始状态管理所使用的Cookie信息响应首部字段
Cookie服务器收到的Cookie信息请求首部字段

该字段有以下几个属性:

Set-Cookie的属性

上图摘自:《图解HTTP》 — 〔日〕上野宣

比较需要注意的是expires这个属性,它指定了浏览器可以发送Cookie的有效期。当该属性省略是,有效期默认为浏览器会话(session)时间段内。另外,一旦Cookie被发送到客户端,服务端就不存在修改它的方法。但是可以通过覆盖已过期的Cookie,实现对客户端Cookie的实质性删除操作。

Cookie: status=enable

当客户端想要获得状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie的形式发送。

结语

HTTP协议博大精深,远远不是一篇文章可以讲完的。如果需要深入学习,推荐该领域的名著《HTTP》权威指南(英文原著名称:HTTP: The Definitive Guide)。