HTTP协议简介

字数 2818阅读 213

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

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

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

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

ps:上图来自维基百科

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

  • HTTP0.9,1990年问世,目前已过时,仅仅支持GET方法;
  • HTTP/1.0,1996年5月发布,至今仍被广泛使用,第一个在通讯中制定版本号的HTTP协议版本;
  • HTTP/1.1,1997年1月发布比1.0版本晚大约半年发布,持久连接默认被采用,能够很好配合代理服务器工作;
  • HTTP/2,在谷歌自行研发的SPDY协议的基础上发展而来,2015年5月作为互联网标准正式发布;
  • HTTP/3,未来版本,正在完善当中;

准备知识

网络通信流程

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

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

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


网络数据通信过程
网络数据通信过程

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

与HTTP关系密切的协议

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

  • IP协议,位于网络层,负责数据包的投递。主要依靠IP、MAC以及ARP协议;
  • TCP协议,提供可靠的字节流服务,主要用于分割数据,并确保数据投递到目的地。该协议有著名的“三次握手”策略;
  • DNS服务,位于应用层,提供域名到IP地址的解析服务(MAC地址需要靠IP地址进行反查得到);

简单的HTTP协议

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

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

  • 两台计算机在使用HTTP协议进行通信时,一端必须为服务器(server),一端必须为客户端(client);
  • HTTP协议规定请求(request)由客户端发起,服务器负责响应(response)并返回;
  • HTTP协议是无状态协议,需要由Cookie技术实现状态保持;

一个示例请求可以如下:

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

一个示例响应可以如下:

请求百度主页的响应
请求百度主页的响应

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

HTTP方法

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

  • GET方法,获取资源。请求参数附在地址栏后面,可见的;
  • POST方法,传输实体主体。一般用于提交表单等操作,且表单的内容在地址栏是不可见的;
  • PUT方法,传输文件。自身不带验证机制,任何人都可以上传,存在安全问题;
  • HEAD方法,获得报文部首。和GET类似,但是服务器不返回报文主体;
  • DELETE方法,删除文件。和PUT相反,同样不带验证机制;
  • OPTIONS方法,查询支持方法。查询服务器开放了哪些HTTP方法;
  • TRACE方法,追踪路径。可以查询发送出去的请求是怎样被加工修改的,容易引发XST攻击,通常不会使用;
  • CONNECT方法,要求使用隧道协议连接代理。主要使用SSL和TLS协议加密信息后传输;

Cookie技术

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

  • 第一次请求:客户端向服务器发起请求,服务器生成cookie用于记住该客户端,将cookie在响应当中返回给客户端,客户端保存该cookie;
  • 第二次以后请求:客户端在请求上主动加上cookie,服务器根据该cookie就可以判断该客户端的身份;
cookie工作示意图
cookie工作示意图

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

HTTP报文内的HTTP信息

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

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

  • 报文(message):HTTP通信的基本单位,由8位组字节流组成;
  • 实体(entity):作为请求或者响应的有效载荷数据被传输,由实体部首和实体主体组成;

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

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

  • 通用首部字段(General Header Fields),请求和响应报文都会使用的首部;
  • 请求首部字段(Request Header Fields),客户端使用的首部,补充请求的附加信息;
  • 响应首部字段(Response Header Fields),服务器使用的首部,补充响应的附加信息;
  • 实体首部字段(Entity Header Fields),针对报文实体使用的首部,补充资源内容更新等于实体有关信息;

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

为Cookie服务的首部字段

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

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

Set-Cookie

该字段有以下几个属性:

Set-Cookie的属性
Set-Cookie的属性

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

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

Cookie

Cookie: status=enable

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

结语

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

推荐阅读更多精彩内容