简单HTTP协议

HTTP协议和TCP/IP协议相同,用于客户端和服务端之间的通信(请求文本或者图像资源的一端称为客户端,提供资源响应的一端称为服务器端)。

在两台计算机之间使用HTTP协议通信,在一条通讯线路上必定有一端是客户端,另一端为服务器端。

1. 通过一个具体的例子说明HTTP响应

首先客户端发送如下请求

1
2
GET /index.htm HTTP/1.1   # 格式为 {方法} {URI} {协议版本} (请求访问某台HTTP服务器上/index.htm页面资源)
Host: hackr.jp

请求报文是由请求方法,请求URI、协议版本、可选的请求部首字段和内容实体构成。

服务器端收到信号后作出如下响应

1
2
3
4
5
6
7
HTTP/1.1 200 OK    # {协议版本} {状态码} {状态码原因短语}
Data: Tue, 10 Jul 2019 06:50:15 GMT
Content-Length: 362
Content-Type text/html

<html>
....

响应报文基本上有协议版本,状态码(表示请求成功或者失败的数字代码)、用以解释状态码的原因短语、可选的响应部首字段以及实体主体构成。

使用HTTP协议不保存之前发送的请求或者响应功能。协议本身并不保存之前一切的请求或者响应的报文信息。但是有些场景(保持登陆状态)引入cookie等技术管理状态。

2. 请求方法总结

当客户端请求访问资源而发送请求时,URI需要作为请求报文中的请求URI包含在内。当不是访问特定资源而是对服务器本身发起请求,可以使用一个*来代替请求URI。

2.1 GET

GET : 获取资源,用来请求已经被URI识别的资源。指定资源经过服务器解析后返回响应的内容。例如

1
2
3
请求:  GET index.html HTTP1.1
Host: www.baidu.com
响应 返回 index.html 的页面资源

2.2 POST

POST : 方法用来传输实体的主体。用来传输实体的主体,例子如下:

1
2
3
4
请求: POST submit.cgi HTTP1.1
Host: www.baidu.com
Content-Length: 1560 (1560字节的处理结果)
响应: 返回 submit.cgi 接收数据的处理结果

2.3 PUT

PUT : 传输文件。类似FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定位置。

1
2
3
4
请求: PUT temp.html HTTP1.1
Host: www.baidu.com
Content-Length: 1560 (1560字节的处理结果)
响应: 响应返回状态码204 (表示该文件已经存在在该服务器上)

因为HTTP1.1 的PUT方法不带验证机制,一般web网站不使用该方法。

2.4 HEAD

HEAD : 获得报文的首部。和GET方法类似,但是只能看到response的HEAD部分。用于确认URI的有效性及资源更新的日期和时间等。

1
2
3
请求:  GET index.html HTTP1.1
Host: www.baidu.com
响应 返回 index.html 的响应首部

2.5 DELETE

DELETE : 删除文件,按请求URI删除服务器上面的指定资源。

1
2
3
请求: DELETE temp.html HTTP1.1
Host: www.baidu.com
响应: 响应返回状态码204 (表示该文件已经被删除)

因为HTTP1.1 的DELETE方法不带验证机制,一般web网站不使用该方法。如果要使用需要配合Web应用的验证机制。

2.6 OPTIONS

OPTIONS : 用来查询指定URI资源支持的方法

1
2
3
4
5
请求: OPTIONS temp.html HTTP1.1
Host: www.baidu.com
响应: HTTP1.1 200 OK
Allow: GET,POST
(返回服务器针对该URI支持的方法)

2.9 总结

这里总结HTTP1.0/1.1支持的方法:

方法 说明 支持的HTTP协议版本
GET 获取资源 1.0、1.1
POST 传输实体主体 1.0、1.1
PUT 传输文件 1.0、1.1
HEAD 获取报文首部 1.0、1.1
DELETE 删除文件 1.0、1.1
OPTIONS 查询支持的方法 1.1
TRACE 追踪路径 1.1
CONNECT 要求用隧道协议连接代理 1.1
LINK 建立和资源之间的联系 1.0
UNLINK 断开连接关系 1.0

3. HTTP通信过程

最开始的HTTP版本,每进行一次HTTP通信就要断开一次TCP连接。这样会导致当请求一个HTML页面的时候需要同时访问其他资源。导致每次都有建立连接和断开连接的资源消耗。增加通讯开销。

1
2
3
4
5
6
7
8
9
10
11
客  建立  ---------SYN----------->  服
TCP <------SYN/ACK----------
连接 ---------ACK----------->

------------HTTP请求---------> 务
户 <-----------HTTP响应----------

断开 <----------FIN----------
端 TCP -----------ACK---------> 器
连接 -----------FIN--------->
<----------ACK----------

HTTP后续的版本开始支持持久连接(HTTP keep-alive)只要任何一端没有提出断开连接,则保持TCP的连接状态。在HTTP1.1中所有连接都是持久连接,使得多数请求以管线化方式发送成为可能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
客  建立  ---------SYN----------->  服
TCP <------SYN/ACK----------
连接 ---------ACK----------->

------------HTTP请求--------->
<-----------HTTP响应----------
------------HTTP请求--------->
户 <-----------HTTP响应---------- 务
...
------------HTTP请求--------->
<-----------HTTP响应----------

断开 <----------FIN----------
端 TCP -----------ACK---------> 器
连接 -----------FIN--------->

4. 使用cookie进行状态管理

HTTP是无状态协议,不对之前发生过的请求和响应状态进行管理。这导致每次跳转页面都需要再次登陆。引入cookie技术后请求过程如下。

1
2
3
4
5
6
7
8
9
10
11
12
       携带账号密码发送给服务器
客 ----------------------------> 服
户 <---------------------------- 务
端 在响应中添加Cookie后返回 器

完成第一步后服务器记住生成的Cookie是向谁发送的
客户端记住Cookie内容

请求中添加Cookie后发送
客 ----------------------------> 服
户 <---------------------------- 务
端 验证Cookie后响应(确认是那个客户端)器