HTTP/1.1

(在本文中我将解释 HTTP/1.1,但现在主要用的是 HTTP/2。我在本文中也会介绍!)

一旦建立了 TCP 连接,我们就可以向服务器发送数据以及从服务器接收数据。我们可以用 HTTP 请求,询问服务器是否可以提供我们所需的数据。然后服务器用 HTTP 响应进行应答。在这个步骤中,我们将最终得到如下流程:

HTTP 请求

典型的 HTTP 请求只是纯文本,至少又如下两部分组成:

  1. 请求行。我们要从服务器获取哪些数据,以及使用的是哪个 HTTP 版本?

  2. 请求头。为服务器提供额外的信息,比如我们将接受那种类型的数据,或者如果数据已经缓存在某个地方,就告诉服务器不要将数据返回给我们。

请求行由三个部分组成:HTTP 方法、资源定位、协议版本。

HTTP 方法有好几种,不过最常用的是:

  1. GET:从资源获取数据(喂,我能得到位于我指定的资源位置的数据(在本例中是 /index.html)吗?)
  2. POST:发送新数据给资源(喂,这里有全新的数据可以添加到资源位置 /index.html!)
  3. PUT:用正在发送的数据替换资源上已有的数据(我知道你在资源位置/index.html上已经有了数据,但这里有其他数据,你应该用这些数据替换所有旧数据)
  4. DELETE: 删除资源(我不再需要 /index.html,请删除它)

请求头是一组字段/值对。有很多可选的请求头,但两个必需的是 Host 和 Connection。

  • Host:我们要面向的域名。在本例中是 www.google.com。

  • Connection:通常,这个值要么是 keep-alive,要么是 close,表示客户端和服务器之间的连接(即TCP连接)应该保持打开还是关闭。通常,对于每个 HTTP 请求,都会打开一个新的 TCP 连接。如果用 keep-alive,就是连续的 HTTP 连接。

典型的 HTTP 请求如下所示:

1
2
3
GET /index.html HTTP/1.1
Host: www.website.com
Connection: close

HTTP 响应

服务器接受和处理 HTTP 请求。基于请求,生成 HTTP 响应。典型的 HTTP 响应由如下部分组成:

  1. 状态行。显示请求是否被成功处理,如果没有,就让我们知道到底哪里出错了。
  2. 响应头。跟请求头一样,响应头给我们提供有关响应的更多信息。它是什么时候请求的?它请求的是什么类型的数据?数据有多少个字节?生成此响应的服务器是什么类型的?
  3. 响应体。如果请求成功了,响应体就包含了我们所请求的资源。

状态行由协议版本(本例中是 HTTTP/1.1)和状态码组成。状态码的值向我们展示请求是如何被处理的:是成功了,还是有错误?

常见的状态码为:

  • 200 OK:一切都很好,请求成功了!
  • 400 Bad Request:发送到服务器的 HTTP 请求的语法无效。
  • 401 Unauthorized:试图请求未经授权的资源。
  • 403 Forbidden:需要更多权限才能访问此资源。
  • 404 Not Found:服务器找不到要的资源。
  • 500 Internal Server Error:由于某种原因,服务器端发生了错误。原因可能有很多种,但是服务器因此无法处理用户请求了。

所有以 2xx 开头的状态码都表示成功,以 4xx 开头的表示客户端错误,而以 5xx 开头的表示服务器端错误。


响应头与请求头一样,是一组包含有关响应信息的键/值对。报头类型很多,但常见的有:

  1. Date:资源是什么时候被请求的?
  2. Server:从哪种类型的服务器请求资源?
  3. Content-Type:请求的内容是什么类型的数据?这显示为 MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)类型。
  4. Content-Length:响应体中的数据有多少字节?

基于文件内容的一些常见的 MIME 类型包括:

典型的响应就是这样子的:

1
2
3
4
5
6
7
HTTP/1.1 200 OK
Date: Fri, 11 Oct 2019 15:47 GMT
Content-Length: 84
Content-Type: text/html
Server: Apache

<html><head><title>My Website</title></head><body><h1>Hello World</h1></body></html>

或者,把每个单独的部分可视化一下:

在响应体中,我们最终得到了我们请求的资源!既然客户端已经得到了请求的数据(在本例中是 HTML),那么我们最终就可以启动在屏幕上显示它们的过程了。


https://www.lydiahallie.dev/blog/http11

欢迎关注我的其它发布渠道