再读斋

Http协议详解

HTTP是一种应用层协议,它通过TCP实现了可靠的数据传输,能够保证数据的完整性、正确性,而TCP对于数据传输控制的优点也能够体现在HTTP上,使得HTTP的数据传输吞吐量、效率得到保证。

对于移动开发来说,网络应用基本上都是C/S架构,也就是客户端/服务器架构。客户端通过向服务器发起特定的请求,服务器返回结果,客户端解析结果,再将结果展示在UI上。客户端与服务器的交互如下所示:

详细的交互流程有如下几步:

  1. 客户端执行网络请求,从URL解析出服务器的主机名。
  2. 将服务器的主机名转换成服务器的IP地址。
  3. 将端口号从URL中解析出来
  4. 建立一条客户端与Web服务器的TCP连接;
  5. 客户端通过输出流向服务器发送一条HTTP请求;
  6. 服务器向客户端返回一条HTTP响应报文;
  7. 客户端从输入流获取报文;
  8. 客户端解析报文,关闭连接;
  9. 客户端将结果显示在UI上;

HTTP请求方式

HTTP提供了几种请求方式,每种请求方式都有不同的作用。被大家熟知的请求方式有7种GET、POST、DELETE、PUT、HEAD、TRACE、OPTIONS。其中PUT、DELETE、POST、GET分别对应着增、删、该、查4个操作,也是客户端运用最多的4个请求。

GET请求

GET的作用是获取服务器的某个资源。下图提供一个例子,客户端用GET方法发起一次HTTP请求,然后服务端将对应的资源返回客户端。

需要注意的是:GET请求的参数都需要放到请求的URL中,第一个参数之前有一个?,参数的格式为:参数名=参数值。参数之间通过“&”连接。

POST请求

POST起初是用来向服务器传递数据的。POST请求通常会用来提交HTML的表单。表单中填好的数据会被传输给服务器,然后由服务器对这些数据进行处理。下图显示一个用POST请求的执行流程。

PUT请求

与GET从服务器读取资源相反,PUT方法会向服务器写入资源。有些发布系统允许用户创建Web页面,并用PUT直接将其传输到Web服务器上。如下图所示:

PUT方法的语义就是让服务器用请求的主题部分来创建一个由所请求的URL命名的新文档,如果那个URL已经存在的话,就用这个资源来替代它。

DELETE请求

DELETE方法所做的事情就是请服务器删除请求URL所指定的资源。但是,客户端无法保证删除操作一定会被执行。因为,HTTP规范允许服务器在不通知客户端的情况下撤销请求。

DELETE方式与GET请求一样,参数都需要放在请求的URL中。下图显示了一个DELETE方法实例。

HEAD请求

HEAD方法与GET方法的行为很类似,但服务器在响应中只返回首部。不会返回实体的主体部分,这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。使用HEAD可以在不获取资源的情况下了解资源的情况(比如,判断其类型);通过查看响应中的状态码,看看某个对象是否存在;通过查看首部,测试资源是否被修改了。服务器开发者必须确保返回的首部与GET请求所返回的首部完全相同。遵循HTTP/1.1规范,就必须实现HEAD方法。如下图所示:

TRACE请求

客户端发起一个请求时,这个请求可能要穿越防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的HTTP请求。TRACE方法运行客户端在最终将请求发送给服务器时,看看它变成了什么样子。

TRACE请求会在目的服务端发起一个“环回”诊断。行程最后一站的服务器会弹回一条TRACE响应,并在响应主体中携带它收到的原始请求报文。这样客户端就可以查看在所有中间HTTP应用程序组成的请求/响应链上,原始报文是否以及如何被毁坏或修改过,如下图所示。

TRACE方法主要用于诊断,也就是说,用于验证请求是否如愿穿过了请求/响应链。

OPTIONS请求

OPTIONS方法请求Web服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法(有些服务器可能只支持对一种特殊类型的对象使用特定的操作)这为客户端应用程序提供了一种手段,使其不用实际访问那些资源就能判定访问各种资源最优方式)。如下图所示:

HTTP报文格式

请求报文

通常一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成。下图为请求报文的一般格式。

  • 起始行

报文的第一行就是起始行,在请求报文中用来说明要以说明方式做什么请求,而在响应报文中初略说明了报文的执行结果。

  • 首部字段

起始行后面有零个或多个首部字段。每个首部字段都包含一个名字和一个值,为了便于解析,两者之间用冒号(如Connection:keep-Alive)来分隔。首部以一个空行结束。添加一个首部字段和添加新行一样简单。

  • 主体

首部字段的空行之后就是可选的报文主体了,其中包含了所以类型的数据。请求主体中包括了要发送给Web服务器的数据;响应主体中装载了要返回给客户端的数据。起始行和首部都是结构化的文本形式,而主体则可以包含任意的二进制数据(如图片、视频、音轨、软件程序)。当然,主体中也可以包含文本。

响应报文

HTTP响应也由3个部分组成,分别是:状态行、消息报头、响应正文。如下所示,HTTP响应的格式与请求的格式十分类似:

1
2
3
4
<状态行>
<响应报文header>
<空行>
[响应报文内容]

在响应报文中第一行用状态信息代替了请求信息。状态行通过提供一个状态码来说明所请求的资源情况。
状态行格式:
HTTP-Version Status-Code Reason-Phrase CRLF

HTTP-Version表示服务器HTTP协议的版本;
Status-Code表示服务器发回的响应状态代码;
Reason-Phrase表示状态代码的文本描述;

状态码由三位数字组成,第一个数字定义了响应的类别,且有5中可能取值。

取值范围 含义
100~199 指示信息。表示请求已接收,继续处理
200~299 请求成功。表示请求已被成功接收理解
300~399 重定向。要完成请求必须进行更进一步的操作
400~499 客户端错误。请求有语法错误或请求无法实现
500~599 服务器端错误。服务器未能实现合法的请求

常见状态代码、状态描述的说明如下:

  • 200 OK:客户端请求成功
  • 202 Accepted 服务器已接收请求,但尚未处理。
  • 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
  • 401 Unauthorized:请求未授权,这个状态码必须和WWW-Authenticate报头域一起使用。
  • 403 Forbidden:服务器收到请求,但是拒绝提供服务。
  • 404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
  • 408 Request Timeout 请求超时
  • 500 Internal Server Error:服务器发生不可预期的错误。
  • 502 Bad Gateway 错误的网关
  • 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK
  • 504 网关超时

下面是一个GET去请求的Response返回示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
HTTP/1.1 200 OK
Date:Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=utf-8
Content-Length: 122
<html>
<head>
<title>开发技术前线</title>
</head>
<body>
</body>
</html>

请求头部

请求头部由键值对组成,每行一对,关键字和值用英文冒号“:”分隔。HTTP规范定义了几种首部字段,应用程序也可以随意发明自己所用的头部。HTTP首部可以分为以下几类,如表所示:

首部类型 作用
通用首部 既可以出现在请求报文中,也可以出现在响应报文中
请求首部 提供更多有关请求的信息
响应首部 提供更多有关响应的信息
实体首部 描述主体的长度和内容,或者资源自身
扩展首部 HTTP规范中没有定义的新首部

请求头部通知服务器关于客户端请求的信息,典型的请求头有。

  • Content-Type:请求数据的格式
  • Content-Length:消息长度
  • Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
  • User-Agent:发出请求的浏览器类型,可以自行设置
  • Accept:客户端可识别的内容类型列表
  • Accept-Encoding:客户端可识别的数据编码
  • Connection:允许客户端和服务器指定与请求/响应连接有关的选项,例如设置为Keep-Alive则表示保持连接
  • Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
刘涤生 wechat