http 协议基础

1.http 协议简介

HTTP(Hypertext Transfer Protocol)是一种用于在网络上进行数据通信的协议。它是万维网(World Wide Web)的基础,用于在客户端和服务器之间传输超文本(Hypertext)文档。HTTP 采用客户端-服务器模型,客户端发送 HTTP 请求,而服务器则回送 HTTP 响应。

HTTP 的工作方式如下:

  1. 客户端发起 HTTP 请求:客户端(通常是一个 Web 浏览器)向服务器发送一个 HTTP 请求,请求可以是获取某个资源,也可以是执行某个操作(如提交表单)。
  2. 服务器处理请求:服务器接收到客户端的请求后,根据请求的内容进行处理。这可能涉及到查询数据库、执行业务逻辑等操作。
  3. 服务器发送 HTTP 响应:服务器根据处理结果生成一个 HTTP 响应,包含了响应状态码、响应头部和响应体。响应状态码表示服务器对请求的处理结果,常见的状态码有 200(成功)、404(资源未找到)等。
  4. 客户端接收 HTTP 响应:客户端接收到服务器发送的 HTTP 响应后,根据响应内容进行处理。响应体通常包含了请求的资源内容,比如 HTML 文档、图片等。
  5. 可选的持续通信:在 HTTP/1.1 及更高版本中,客户端和服务器之间可以建立持续连接,使得多个请求和响应可以通过同一个 TCP 连接完成,以提高性能和效率。

HTTP 协议是无状态的,即服务器不会保留与客户端之前的通信状态。这意味着每个请求都是独立的,服务器不能直接识别两个请求是否来自同一个客户端。为了在请求之间保持状态,可以使用一些技术,如 Cookie 和 Session。

HTTP 协议有许多不同的方法(也称为 HTTP 动词),最常见的是 GET、POST、PUT 和 DELETE。这些方法用于指定对资源的不同操作,如获取资源、创建资源、更新资源和删除资源。

除了基本的 HTTP 协议,还有一些扩展的协议和标准,如 HTTPS(通过使用 SSL/TLS 加密保护通信)、HTTP/2(引入了多路复用和服务器推送等特性以提高性能)、HTTP/3(基于 UDP 的新一代 HTTP 协议)等。

总结来说,HTTP 是一种用于在客户端和服务器之间传输数据的协议,它在万维网中起着至关重要的作用,使得用户能够通过浏览器获取和与互联网上的资源进行交互。

http 通信示例

示例 1

GET /index.htm HTTP/1.1
Host: hackr.jp

起始行开头的GET表示请求访问服务器的类型,称为方法(method)。

随后的字符串 /index.htm 指明了请求访问的资源对象,也叫做请求 URI(request-URI)。

最后的 HTTP/1.1,即 HTTP 的版本号,用来提示客户端使用的 HTTP 协议功能。

综合来看,这段请求内容的意思是:请求访问某台 HTTP 服务器上的/index.htm 页面资源。

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

示例 2

客户端的发送报文

方法  URI         协议版本
POST /form/entry HTTP/1.1
Host:hackr.jp
Connection:keep-alive
Content-type:application/x-www-form-urlencoded
Content-Length:16

内容实体:
name=ueno&age=37

服务端的报文


协议版本   状态码  状态码的原因短语
HTTP/1.1  200    OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html

<html>
...

在起始行开头的 HTTP/1.1 表示服务器对应的 HTTP 版本。

紧挨着的 200 OK 表示请求的处理结果的状态码(status code)和原因短语(reason-phrase)。

下一行显示了创建响应的日期时间,是首部字段(header field)内的一个属性。

接着以一空行分隔,之后的内容称为资源实体的主体(entity body)。

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

2.http 协议报文

HTTP 方法

HTTP/1.1 中可使用的方法

GET 获取资源

GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容。 也就是说,如果请求的资源是文本,那就保持原样返回; 如果是像 CGI(Common Gateway Interface,通用网关接口)那样的程序,则返回经过执行后的输出结果。

请求
GET /index.html HTTP/1.1
Host: www.hackr.jp

响应
返回 index.html 的页面资源

POST:传输实体主体

POST 方法用来传输实体的主体。 虽然用 GET 方法也可以传输实体的主体,但一般不用 GET 方法进行 传输,而是用 POST 方法。虽说 POST 的功能与 GET 很相似,但 POST 的主要目的并不是获取响应的主体内容。

请求
POST /submit.cgi HTTP/1.1
Host: www.hackr.jp
Content-Length: 1560(1560字节的数据)

响应
返回 submit.cgi 接收数据的处理结果

PUT:传输文件

PUT 方法用来传输文件。就像 FTP 协议的文件上传一样,要求在请 求报文的主体中包含文件内容,然后保存到请求 URI 指定的位置。 但是,鉴于 HTTP/1.1 的 PUT 方法自身不带验证机制,任何人都可以 上传文件 , 存在安全性问题,因此一般的 Web 网站不使用该方法。若 配合 Web 应用程序的验证机制,或架构设计采用 REST(REpresentational State Transfer,表征状态转移)标准的同类 Web 网站,就可能会开放使用 PUT 方法。

请求
PUT /example.html HTTP/1.1
Host: www.hackr.jp
Content-Type: text/html
Content-Length: 1560(1560 字节的数据)

响应
响应返回状态码 204 No Content(比如 :该 html 已存在于服务器上)

HEAD:获得报文首部

HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时间等。

  • 和 GET 一样,但不返回报文主体
请求
HEAD /index.html HTTP/1.1
Host: www.hackr.jp

响应
返回index.html有关的响应首部

DELETE:删除文件

DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按 请求 URI 删除指定的资源。 但是,HTTP/1.1 的 DELETE 方法本身和 PUT 方法一样不带验证机 制,所以一般的 Web 网站也不使用 DELETE 方法。当配合 Web 应用 程序的验证机制,或遵守 REST 标准时还是有可能会开放使用的

请求
DELETE /example.html HTTP/1.1
Host: www.hackr.jp

响应
响应返回状态码 204 No Content(比如 :该 html 已从该服务器上删除)

OPTIONS:询问支持的方法

OPTIONS 方法用来查询针对请求 URI 指定的资源支持的方法

  • 使用 OPTIONS 方法的请求·响应的例子
请求:
OPTIONS * HTTP/1.1
Host: www.hackr.jp

响应:
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
(返回服务器支持的方法)

TRACE:追踪路径

TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。 发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服 务器端就将该数字减 1,当数值刚好减到 0 时,就停止继续传输,最 后接收到请求的服务器端则返回状态码 200 OK 的响应。 客户端通过 TRACE 方法可以查询发送出去的请求是怎样被加工修改 / 篡改的。这是因为,请求想要连接到源目标服务器可能会通过代理 中转,TRACE 方法就是用来确认连接过程中发生的一系列操作。 但是,TRACE 方法本来就不怎么常用,再加上它容易引发 XST(Cross-Site Tracing,跨站追踪)攻击,通常就更不会用到了。

请求
TRACE / HTTP/1.1
Host: hackr.jp
Max-Forwards: 2
HTTP/1.1 200 OK
Content-Type: message/http

响应
Content-Length: 1024
TRACE / HTTP/1.1
Host: hackr.jp
Max-Forwards: 2(返回响应包含请求内容)

CONNECT:要求用隧道协议连接代理

CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。 主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容 加 密后经网络隧道传输。

  • CONNECT 方法的格式:
  CONNECT 代理服务器名:端口号 HTTP 版本

示例

请求
CONNECT proxy.hackr.jp:8080 HTTP/1.1
Host: proxy.hackr.jp

响应
HTTP/1.1 200 OK(之后进入网络隧道)

使用方法下达命令

方法说明支持的 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
UNLINE 断开连接关系 1.0

在这里列举的众多方法中,LINK 和 UNLINK 已被 HTTP/1.1 废弃,不再支持。

持久连接

HTTP 协议的初始版本中,每进行一次 HTTP 通信就要断开一次 TCP 连接。

为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了 持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或 HTTP connection reuse)的方法。持久连接的特点是,只要任意一端 没有明确提出断开连接,则保持 TCP 连接状态

持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额 外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使 HTTP 请求和响应能够更早地结束,这样 Web 页面的显示速度也就相 应提高了。

在 HTTP/1.1 中,所有的连接默认都是持久连接,但在 HTTP/1.0 内并 未标准化。虽然有一部分服务器通过非标准的手段实现了持久连接, 但服务器端不一定能够支持持久连接。毫无疑问,除了服务器端,客 户端也需要支持持久连接。

管线化

持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从 前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术 出现后,不用等待响应亦可直接发送下一个请求。

HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。

假设要求登录认证的 Web 页面本身无法进行状态的管理(不记录已登录的状态),那么每次跳转新页面不是要再次登录,就是要在每次 请求报文中附加参数来管理登录状态。

不可否认,无状态协议当然也有它的优点。由于不必保存状态,自然可减少服务器的 CPU 及内存资源的消耗。从另一侧面来说,也正是 因为 HTTP 协议本身是非常简单的,所以才会被应用在各种场景里。

保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信 息来控制客户端的状态。

Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器 发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一 个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

HTTP 请求报文和响应报文的内容如下:

  • 1.请求报文(没有 Cookie 信息的状态)
GET /reader/ HTTP/1.1
Host: hackr.jp
*首部字段内没有Cookie的相关信息
  • 2.响应报文(服务器端生成 Cookie 信息)
HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 07:12:20 GMT
Server: Apache <Set-Cookie: sid=1342077140226724; path=/; expires=Wed,10-Oct-12 07:12:20 GMT>
Content-Type: text/plain; charset=UTF-8
    1. 请求报文(自动发送保存着的 Cookie 信息)
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724

3. HTTP 报文内的 HTTP 信息

3.1 HTTP 报文

用于 HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。 HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。

HTTP 报文大致可分为报文首部和报文主体两块。两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主体。

Alt text

3.2 请求报文及响应报文的结构

Alt text

请求报文和响应报文的首部内容由以下数据组成:

  • 请求行

包含用于请求的方法,请求 URI 和 HTTP 版本。

  • 状态行

包含表明响应结果的状态码,原因短语和 HTTP 版本。

  • 首部字段

包含表示请求和响应的各种条件和属性的各类首部。一般有 4 种首部,分别是:通用首部、请求首部、响应首部和实体首 部。

3.3 编码提升传输速率

HTTP 在传输数据时可以按照数据原貌直接传输,但也可以在传输过 程中通过编码提升传输速率。通过在传输时编码,能有效地处理大量 的访问请求。但是,编码的操作需要计算机来完成,因此会消耗更多 的 CPU 等资源。

3.3.1 报文主体和实体主体的差异

  • 报文(message)

是 HTTP 通信中的基本单位,由 8 位组字节流(octet sequence, 其中 octet 为 8 个比特)组成,通过 HTTP 通信传输。

  • 实体(entity)

作为请求或响应的有效载荷数据(补充项)被传输,其内容由实 体首部和实体主体组成。 HTTP 报文的主体用于传输请求或响应的实体主体。 通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体 主体的内容发生变化,才导致它和报文主体产生差异。 报文和实体这两个术语在之后会经常出现,请事先理解两者的差异。

3.3.2 压缩传输的内容编码

向待发送邮件内增加附件时,为了使邮件容量变小,我们会先用 ZIP 压缩文件之后再添加附件发送。

HTTP 协议中有一种被称为内容编码的功能也能进行类似的操作。

内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。

常用的内容编码有以下几种:

  • gzip(GNU zip)
  • compress(UNIX 系统的标准压缩)
  • deflate(zlib)
  • identity(不进行编码)

3.3.3 分割发送的分块传输编码

在 HTTP 通信过程中,请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。

在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。

这种把实体主体分块的功能称为分块传输编码(Chunked TransferCoding)。

分块传输编码会将实体主体分成多个部分(块)。每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用“0(CR+LF)”来标 记。使用分块传输编码的实体主体会由接收的客户端负责解码,恢复到编码前的实体主体。

HTTP/1.1 中存在一种称为传输编码(Transfer Coding)的机制,它可以在通信时按某种编码方式传输,但只定义作用于分块传输编码中。

4. HTTP 状态码

HTTP 状态码负责表示客户端 HTTP 请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作。

状态码的类别:

类别原因短语
1XXInformational(信息性状态码) 接收的请求正在处理
2XXSuccess(成功状态码) 请求正常处理完毕
3XXRedirection(重定向状态码) 需要进行附加操作以完成请求
4XXClient Error(客户端错误状态码) 服务器无法处理请求
5XXServer Error(服务器错误状态码) 服务器处理请求出错

4.1 200 OK(正常)

表示从客户端发来的请求在服务器端被正常处理了。在响应报文内,随状态码一起返回的信息会因方法的不同而发生改变。

比如,使用 GET 方法时,对应请求资源的实体会作为响应返回;而使用 HEAD 方法时,对应请求资源的实体首部不随报文主体作为响应返回(即在响应中只返回首部,不会返回实体的主体部分)。

4.2 204 No Content(不含实体的主体部分)

该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。

比如,当从浏览器发出请求处理后,返回 204 响应,那么浏览器显示的页面不发生更新。

一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。

4.3 206 Partial Content(指定范围的实体内容)

该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。

4.4 301 Moved Permanently(永久性重定向)

永久性重定向。该状态码表示请求的资源已被分配了新的 URI,以后 应使用资源现在所指的 URI。也就是说,如果已经把资源对应的 URI 保存为书签了,这时应该按 Location 首部字段提示的 URI 重新保存。 像下方给出的请求 URI,当指定资源路径的最后忘记添加斜杠“/”,就 会产生 301 状态码。

4.5 302 Found(临时性重定向)

临时性重定向。该状态码表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。

和 301 Moved Permanently 状态码相似,但 302 状态码代表的资源不是被永久移动,只是临时性质的。

换句话说,已移动的资源对应的 URI 将来还有可能发生改变。比如,用户把 URI 保存成书签,但不会像 301 状态码出现时那样去更新书签, 而是仍旧保留返回 302 状态码的页面对应的 URI。

4.6 303 See Other(对应的资源在其他)

该状态码表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。 303 状态码和 302 Found 状态码有着相同的功能,但 303 状态码明确表示客户端应当采用 GET 方法获取资源,这点与 302 状态码有区 别。

比如,当使用 POST 方法访问 CGI 程序,其执行后的处理结果是希望客户端能以 GET 方法重定向到另一个 URI 上去时,返回 303 状态 码。虽然 302 Found 状态码也可以实现相同的功能,但这里使用 303 状态码是最理想的。 当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次发送。 301、302 标准是禁止将 POST 方法改变成 GET 方法的,但实际使用时大家都会这么做。

4.7 304 Not Modified(未更改)

该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。304 状态码返回时,不包含任何响应 的主体部分。304 虽然被划分在 3XX 类别中,但是和重定向没有关系。

- 附带条件的请求是指采用 GET 方法的请求报文中包含 If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since 中任一首部。)

4.8 307 Temporary Redirect(临时重定向)

临时重定向。该状态码与 302 Found 有着相同的含义。尽管 302 标准禁止 POST 变换成 GET,但实际使用时大家并不遵守。 307 会遵照浏览器标准,不会从 POST 变成 GET。但是,对于处理响应时的行为,每种浏览器有可能出现不同的情况。

4.9 400 Bad Request(存在语法错误)

该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像 200 OK 一样对待该状态码。

4.10 401 Unauthorized(未认证)

该状态码表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示 用 户认证失败。返回含有 401 的响应必须包含一个适用于被请求资源的 WWW-Authenticate 首部用以质询(challenge)用户信息。 当浏览器初次接收到 401 响应,会弹出认证用的对话窗口。

4.11 403 Forbidden(禁止访问)

该状态码表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分 对原因进行描述,这样就能让用户看到了。

未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源 IP 地址试图访问)等列举的情况都可能是发生 403 的原因。

4.12 404 Not Found(未找到资源)

该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。

4.13 500 Internal Server Error(服务器错误)

该状态码表明服务器端在执行请求时发生了错误。也有可能是 Web 应用存在的 bug 或某些临时的故障。

4.14 503 Service Unavailable(服务不可用)

该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。 如果事先得知解除以上状况需要的时间,最好写入 RetryAfter 首部字段再返回给客户端。

5. 常见的协议

  • FTP(File Transfer Protocol)

传输文件时使用的协议。该协议历史久远,可追溯到 1973 年前 后,比 TCP/IP 协议族的出现还要早。虽然它在 1995 年被 HTTP 的 流量(Traffic)超越,但时至今日,仍被广泛沿用。

  • NNTP(Network News Transfer Protocol)

用于 NetNews 电子会议室内传送消息的协议。在 1986 年前后出 现,属于比较古老的一类协议。现在,利用 Web 交换信息已成主 流,所以该协议已经不怎么使用了。

  • Archie

搜索 anonymous FTP 公开的文件信息的协议。1990 年前后出现,现 在已经不常使用。

  • WAIS(Wide Area Information Servers)

以关键词检索多个数据库使用的协议。1991 年前后出现。由于现 在已经被 HTTP 协议替代,也已经不怎么使用了。

-Gopher

查找与互联网连接的计算机内信息的协议。1991 年前后出现,由 于现在已经被 HTTP 协议替代,也已经不怎么使用了。

Contributors: masecho, --