《图解HTTP》笔记

# 《图解HTTP》笔记

[TOC]

# 一、必要的概念

# 1.1 网络四层

# 1.1.1 应用层

  • 向用户提供应用服务时通信的活动。

  • 该层有FTP(FIle Transfer Protocol,文件传输协议)、DNS(Domain Name System,域名系统)、HTTP协议。

# 1.1.2 传输层

  • 提供用于网络连接中的两台计算机之间的数据传输。

  • 该层有TCP(Transmission Control Protocol,传输控制协议)、UDP(User Data Protocol,用户数据报协议)。

# 1.1.3 网络层( 又名网络互连层)

  • 用来处理在网络上流动的数据包。 (数据包是网络传输的最小数据单位。) 与对方计算机之间通过多台计算机或网络设备进行传输时, 网络层所起的作用就是在众多的选项内选择一条传输路线。

  • 该层包括IP(Internet Protocol) 网际协议。

# 1.1.4 链路层( 又名数据链路层, 网络接口层):

  • 处理连接网络的硬件部分。

  • 该层包括控制操作系统、 硬件的设备驱动、 NIC(Network Interface Card, 网络适配器, 即网卡) , 及光纤等物理可见部分(还包括连接器等一切传输媒介) 。


从发送端到接收端

发送端在层与层之间传输数据时, 每经过一层时必定会被打上一个该层所属的首部信息(数据信息的包装叫封装)。 反之, 接收端在层与层传输数据时, 每经过一层时会把对应的首部消去。


# 1.2 IP 协议

  • 把各种数据包传送给对方。

  • 保证确实传送到对方那里的两个重要的条件是

    1. IP地址
      1. 指明了节点被分配到的地址
      2. 可变换
    2. MAC地址(Media Access Control Address)
      1. 指网卡所属的固定地址
      2. 不可更改

在网络上, 通信的双方在同一局域网(LAN) 内的情况是很少的, 通常是经过多台计算机和网络设备中转才能连接到对方。 而在进行中转时, 会利用下一站中转设备的 MAC地址来搜索下一个中转目标。


# 1.3 ARP协议(AddressResolution Protocol)

  • 解析地址的协议

    根据通信方的 IP 地址就可以反查出对应的 MAC 地址

# 1.4 路由选择(routing)机制

  • 在到达通信目标前的中转过程中, 那些计算机和路由器等网络设备只能获悉很粗略的传输路线。

路由选择机制

有点像快递公司的送货过程。 想要寄快递的人, 只要将自己的货物送到集散中心, 就可以知道快递公司是否肯收件发货, 该快递公司的集散中心检查货物的送达地址, 明确下站该送往哪个区域的集散中心。 接着, 那个区域的集散中心自会判断是否能送到对方的家中。


# 1.5 TCP协议

  • 提供可靠字节流服务
    • 字节流服务(Byte Stream Service): 为了方便传输, 将大
  • 块数据分割成以报文段(segment)
    • 为单位的数据包进行管理。
    • 可靠:确保数据能到达目

# 1.6 三次握手(three-way handshaking) 策略


三次握手

  • TCP的标志(flag)
    • SYN(synchronize) 同步
    • ACK(acknowledgement)确认
    • 若在握手过程中某个阶段莫名中断, TCP 协议会再次以相同的顺序发送相同的数据包。

# 1.7 DNS服务

  • 通过域名查找 IP 地址, 或逆向从 IP 地址反查域名 DNS服务 浏览网页请求

# 1.8 URI(Uniform Resource Identifier,统一资源标识符)

  • 由某个协议方案表示的资源的定位标识符

# 1.9 绝对URI

绝对URI

# 1.10 协议方案名

  • 不区分字母大小写, 最后附一个冒号(:)
  • 也可使用 data: 或 javascript: 这类指定数据或脚本程序的方案名

# 1.11 登录信息( 认证)

  • 指定用户名和密码作为从服务器端获取资源时必要的登录信息
  • 此项是可选项。

# 1.12 服务器地址

  • 使用绝对 URI 必须指定待访问的服务器地址。
  • 地址可以是类似hackr.jp 这种 DNS 可解析的名称,
  • 或是 192.168.1.1 这类 IPv4 地址名,
  • 还可以是 [0:0:0:0:0:0:0:1] 这样用方括号括起来的 IPv6 地址名。

# 1.13 服务器端口号

  • 指定服务器连接的网络端口号。
  • 此项也是可选项,
  • 若用户省略则自动使用默认端口号。

# 1.14 带层次的文件路径

  • 指定服务器上的文件路径来定位特指的资源。

# 1.15 查询字符串

  • 可以使用查询字符串传入任意参数。
  • 此项可选。

# 1.16 片段标识符

  • 通常可标记出已获取资源中的子资源(文档内的某个位置) 。
  • 该项也为可选项。

# 1.17 RFC(Request for Comments, 征求修正意见书)

  • 用来制定 HTTP 协议技术标准的文档
  • 通常, 应用程序会遵照由 RFC 确定的标准实现。

# 二、通过请求和响应的交换达成通信

请求和响应

# 2.1 请求报文

请求报文

# 2.2 响应报文

响应报文

# 2.3 HTTP是不保存状态协议

  • HTTP 协议自身不具备保存之前发送过的请求或响应的功能 HTTP是不保存状态协议

# 三、告知服务器意图的 HTTP/1.1方法

  • 方法名区分大小写, 注意要用大写字母
  • 响应的意思其实是请求执行成功了, 但无数据返回。

# 3.1 HTTP方法

# 3.1.1GET : 获取资源

请求 GET /index.html HTTP/1.1Host: www.hackr.jpIf-Modified-Since: Thu, 12 Jul 2012 07:30:00 GMT
响应 仅返回2012年7 月12日7 点30分以后更新过的index.html页面资源。 如果未有内容更新, 则以状态码304 Not Modified作为响应返回

# 3.1.2 POST: 传输实体主体

  • 虽然用 GET 方法也可以传输实体的主体, 但一般不用 GET 方法进行传输, 而是用 POST 方法。
  • 虽说 POST 的功能与 GET 很相似, 但POST 的主要目的并不是获取响应的主体内容。
请求 POST /submit.cgi HTTP/1.1Host: www.hackr.jpContent-Length: 1560(1560字节的数据)
响应 返回 submit.cgi 接收数据的处理结果
# 3.1.2.1 get和post的区别

get相对不隐私,post相对隐私。

  1. 浏览器回退时,get不会重新请求,但是post会重新请求。
  2. get请求会被浏览器主动缓存,而post不会。
  3. get请求的参数,会报保留在浏览器的历史记录里,而post不会。做业务时要注意。为了防止CSRF攻击,很多公司把get统一改成了post。
  4. get请求在url中传递的参数有大小限制,基本是2kb,不同的浏览器略有不同。而post没有限制。
  5. get的参数是直接暴露在url上的,相对不安全。而post是放在请求体中的。

# 3.1.3 PUT: 传输文件

  • 鉴于 HTTP/1.1 的 PUT 方法自身不带验证机制, 任何人都可以上传文件 , 存在安全性问题, 因此一般的 Web 网站不使用该方法。
  • 若配合 Web 应用程序的验证机制, 或架构设计采用REST(REpresentational State Transfer, 表征状态转移) 标准的同类Web 网站, 就可能会开放使用 PUT 方法。
请求 PUT /example.html HTTP/1.1Host: www.hackr.jpContent-Type: text/htmlContent-Length: 1560(1560 字节的数据)
响应 响应返回状态码 204 No Content(比如 : 该 html 已存在于服务器上)

# 3.1.4 HEAD: 获得报文首部

请求 HEAD /index.html HTTP/1.1Host: www.hackr.jp
响应 返回index.html有关的响应首部

# 3.1.5 DELETE: 删除文件

  • 与 PUT 相反的方法。
请求 DELETE /example.html HTTP/1.1Host: www.hackr.jp
响应 响应返回状态码 204 No Content(比如 : 该 html 已从该服务器上删除)

# 3.1.6 OPTIONS: 询问支持的方法

  • 用来查询针对请求 URI 指定的资源支持的方法。
  • 如果不是访问特定资源而是对服务器本身发起请求, 可以用一个 * 来代替请求 URI。
请求 OPTIONS * HTTP/1.1Host: www.hackr.jp
响应 HTTP/1.1 200 OKAllow: GET, POST, HEAD, OPTIONS(返回服务器支持的方法)

# 3.1.7 TRACE: 追踪路径

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

TRACE: 追踪路径

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

  • 要求在与代理服务器通信时建立隧道, 实现用隧道协议进行 TCP 通信。
  • 主要使用 SSL(Secure Sockets Layer, 安全套接层) 和 TLS(Transport Layer Security, 传输层安全) 协议把通信内容加密后经网络隧道传输。
  • 格式:CONNECT 代理服务器名:端口号 HTTP版本
请求 CONNECT proxy.hackr.jp:8080 HTTP/1.1Host: proxy.hackr.jp
响应 HTTP/1.1 200 OK(之后进入网络隧道)

# 3.2 持久连接(HTTP Persistent Connections, 也称为 HTTP keep-alive 或HTTP connection reuse)

  • 旨在建立 1 次 TCP 连接后进行多次请求和响应的交互
  • 减少了 TCP 连接的重复建立和断开所造成的额外开销
  • 减轻了服务器端的负载。
  • 使HTTP 请求和响应能够更早地结束, Web 页面显示速度提高了

# 3.3 管线化(pipelining)

  • 能够做到同时并行发送多个请求, 而不需要一个接一个地等待响应
  • Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的 首部字段信息, 通知客户端保存 Cookie。 当下次客户端再往该服务器 发送请求时, 客户端会自动在请求报文中加入 Cookie 值后发送出 去。
  • 服务器端发现客户端发送过来的 Cookie 后, 会去检查究竟是从哪一 个客户端发来的连接请求, 然后对比服务器上的记录, 最后得到之前 的状态信息。
  • 通常, 报文主体等于实体主体。只有当传输中进行编码操作时, 实体主体的内容发生变化, 才导致它和报文主体产生差异。

没有 Cookie 信息状态下的请求 没有 Cookie 信息状态下的请求

  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 第 2 次以后( 存有 Cookie 信息状态) 的请求
  3. 请求报文( 自动发送保存着的 Cookie 信息)
    • GET /image/ HTTP/1.1
    • Host: hackr.jp
    • Cookie: sid=1342077140226724

# 3.6 内容编码

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

# 3.7 分块传输编码(Chunked Transfer Coding)

  • 把实体主体分块
  • 在 HTTP 通信过程中, 请求的编码实体资源尚未全部传输完成之前, 浏览器无法显示请求页面。 在传输大容量数据时, 通过把数据分割成 多块, 能够让浏览器逐步显示页面。
  • 分块传输编码会将实体主体分成多个部分(块)。
  • 每一块都会用十六进制来标记块的大小, 而实体主体的最后一块会使用“0(CR+LF)”来标记。 分块传输编码

# 3.8 MIME(Multipurpose Internet Mail Extensions, 多用途因特网邮件扩展) 机制

- 发送邮件时, 我们可以在邮件里写入文字并添加多份附件。
- 在 MIME 扩展中用一种称为多部分对象集合(Multipart)的方法, 容纳多份不同类型的数据。
- 多部分对象集合包含的对象如下:
    - multipart/form-data
        - 在 Web 表单文件上传时使用。
    - multipart/byteranges
        - 状态码 206(Partial Content, 部分内容) 响应报文包含了多个范围的内容时使用。
          在 HTTP 报文中使用多部分对象集合时, 需要在首部字段里加上Content-type。

# 3.9 范围请求( Range Request)

- 指定范围发送的请求

范围请求

  • 执行范围请求时, 会用到首部字段 Range 来指定资源的 byte 范围。
    • byte 范围的指定形式如下:
      • 5001~10 000 字节
        • Range: bytes=5001-10000
      • 从 5001 字节之后全部的
        • Range: bytes=5001-
      • 从一开始到 3000 字节和 5000~7000 字节的多重范围
        • Range: bytes=-3000, 5000-7000
      • 针对范围请求
        • 响应会返回状态码为 206 Partial Content 的响应报文。
      • 对于多重范围的范围请求
        • 响应会在首部字段 ContentType 标明 multipart/byteranges 后返回响应报文。
      • 如果服务器端无法响应范围请求
        • 则会返回状态码 200 OK 和完整的实体内容

# 3.10 内容协商(Content Negotiation)

  • 客户端和服务器端就响应的资源内容进行交涉, 然后提供给客户端最为适合的资源。
  • 以响应资源的语言、 字符集、 编码方式等作为判断的基准。 内容协商

# 四、HTTP 状态码

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

# 4.1 2XX 成功

# 4.1.1 200 OK

200 OK

# 4.1.2 204 No Content

204 No Content

# 4.1.3 206 Partial Content

206 Partial Content

# 4.2 3XX 重定向

  • 表明浏览器需要执行某些特殊的处理以正确处理请求

# 4.2.1 301 Moved Permanently

  • 永久性重定向。
  • 该状态码表示请求的资源已被分配了新的 URI, 以后应使用资源现在所指的 URI。
  • 也就是说, 如果已经把资源对应的 URI保存为书签了, 这时应该按 Location 首部字段 提示的 URI 重新保存。 301 Moved Permanently

# 4.2.2 302 Found

  • 临时性重定向。
  • 请求的资源已被分配了新的 URI, 希望用户(本次) 能使用新 URI 访问
  • 代表的资源不是被永久移动, 只是临时性质的。 换句话说, 已移动的资源对应的URI 将来还有可能发生改变。 302 Found

# 4.2.3 303 See Other

  • 表示由于请求对应的资源存在着另一个 URI, 应使用 GET方法定向获取请求的资源。
  • 303 状态码和 302 Found 状态码有着相同的功能, 但 303 状态码明确表示客户端应当采用 GET 方法获取资源, 这点与 302 状态码有区别。 303 See Other
  • 301、 302、 303 响应状态码返回时, 几乎所有的浏览器都会把POST 改成 GET, 并删除请求报文内的主体, 之后请求会自动再次发送。
  • 301、 302 标准是禁止将 POST 方法改变成 GET 方法的, 但实际使用时大家都会这么做。

# 4.2.4 304 Not Modified

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

# 4.2.5 307 Temporary Redirect

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

# 4.3 4XX 客户端错误

# 4.3.1 400 Bad Request

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

# 4.3.2 401 Unauthorized

  • 表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证) 的认证信息。
  • 另外若之前已进行过 1 次请求, 则表示用 户认证失败。 401 Unauthorized

# 4.3.3 403 Forbidden

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

# 4.3.4 404 Not Found

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

# 4.4 5XX 服务器错误

# 4.4.1 500 Internal Server Error

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

# 4.4.2 503 Service Unavailable

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

# 4.5 汇总

类别 原因短语
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错
  • 状态码和实际状况不一定一致。