写在前面
当我们在浏览器的地址栏里输入 URL 时,信息会被送往某处,然后从某处得到回复,最终将内容呈现在 Web 页面上。Web 使用一种名为 HTTP(HyperText Transfer Protocol,超文本传输协议) 的协议作为规范,完成客户端到服务端的一系列运作流程。
网络基础 TCP/IP
为了理解 HTTP,不得不先了解一下 TCP/IP 协议族。TCP/IP 协议族按层次分为五层:应用层、传输层、网络层、数据链路层和物理层。分层的好处就是降低耦合度,各层专注于自己的事。各层的作用如下:
- 应用层 - 向用户提供应用服务。著名的协议有 FTP、DNS,还有这篇文章的主体 HTTP 等。
- 传输层 - 提供处于网络连接中的两台计算机之间的数据传输。著名的两个协议是 TCP 和 UDP。
- 网络层 - 处理在网络上流动的数据包。比如 IP 协议。
- 数据链路层 - 建立数据链路,传输数据帧。
- 物理层 - 以二进制形式在物理媒介上传输数据。
HTTP 协议的密友:TCP、IP 和 DNS
IP(网际协议)
IP 协议位于网络层,它的作用是在源地址和目的地址之间传送数据包,要保证确实传送到对方那里,有两个重要的条件是 IP 地址和 MAC 地址。我们先来看一张图:
这张图里发生了什么?首先发送端确定好它想给 IP 地址为 192.0.43.10 的地方发送数据包,然后它会先查询 ARP 表以获得该 IP 对应的 MAC 地址,但它发现目的主机与自己并不在同一个局域网内,那么 ARP 就会查询到出口路由的 MAC 地址,并且向其发送数据,该路由器拿到数据后,与上述的操作同理,直至发送到目的主机上。
TCP(传输控制协议)
TCP 协议是可靠的传输协议,意味着它能够把数据准确可靠地传送给对方,既不丢包还能保证顺序正确。为了保证这种可靠性,TCP 有著名的三次握手和四次挥手。
三次握手:(客)我给你发了数据包 - (服)明白!我收到了你给我的数据包 - (客)好的!
四次挥手:客户端和服务端都可以发起挥手,这里假设由服务端发起。(服)我没数据要发给你了 - (客)好的,我收到了。但是我还没准备好,请稍等 - (客)我这里也 OK 了,可以关闭连接了 - (服)好的,再见
DNS(域名服务)
计算机可以被赋予 IP 地址,也可以被赋予主机名和域名。相较前者来说,用户更喜欢后者,毕竟没有人喜欢记一组长长的数字。DNS 服务应运而生,DNS 协议提供通过域名查找 IP 地址,或逆向从 IP 地址反查域名的服务。
一些碎碎念:DNS 解析的时候,既会用到 TCP 协议也会用到 UDP 协议。DNS 的规范规定了两种类型的 DNS 服务器:主 DNS 服务器和从 DNS 服务器。当从域名服务器启动后,需要与主域名服务器通信并加载数据信息,这被称为区传送。后续从域名服务器也会定时向主域名服务器进行查询以便了解数据变动,如有变动,就会执行区传送。区传送主要使用 TCP 协议,主要基于以下两点考虑:第一点是区传送的数据传输的信息量很大;二是该传输需要可靠。而域名解析时会使用 UDP 协议,主要是因为客户端查询域名时,服务器返回的信息量很小,同时,使用 UDP 无需三次握手,可以降低域名服务器的负载。
HTTP 中的数据
HTTP 报文
在 HTTP 协议中,数据交换的格式就是 HTTP 报文。报文大致可分为报文首部和报文主体两部分,通常,并不一定有报文主体。客户端的 HTTP 报文为请求报文,服务端的 HTTP 报文为响应报文。请求报文第一行为请求行,包含用于请求的方法、请求 URI 和 HTTP 版本。响应报文第一行为状态行,包含表明响应结果的 HTTP 版本、状态码和原因短语,
编码提升传输速率
HTTP 在传输时可以按照数据原貌直接传输,也可以在传输过程中通过编码提升传输速率。常用的内容编码有:
- gzip(GNU zip)
- compress(UNIX 系统的标准压缩)
- deflate(zlib)
- identity(不进行编码)
虽然编码后传输可以提高效率,但是在编码实体资源尚未完全传输完成之前,浏览器无法显示请求页面。所以,要应用分块传输编码以将实体主体进行分块,使得浏览器可以逐步展示页面。
使用方法给服务端下达命令
- GET - 获取资源
- POST - 传输实体主体
- PUT - 传输文件
- HEAD - 获得报文头部
- DELETE - 删除文件
- OPTIONS - 询问支持的方法
- TRACE - 追踪路径
- CONNECT - 要求用隧道协议连接代理
以上的 HTTP 方法中,常用的主要是 GET/POST/PUT/DELETE 四种。
状态码告知客户端请求结果
以下是一些代表性的状态码。在现实生活中,也可以自定义状态码,只要遵守状态码类别的定义即可。
2XX 成功
- 200 OK - 表示从客户端发来的请求被正常处理了
- 204 No Content - 请求处理成功,但没有资源可返回
- 206 Partial Content - 表示客户端进行了范围请求(Content-Range),而服务端成功执行了这部分的 GET 请求
3XX 重定向
- 301 Moved Permanently - 永久性重定向
- 302 Found - 临时性重定向
- 303 See Other - 资源的 URI 已更新,应使用 GET 方法定向获取请求的资源
- 304 Not Modified - 表示客户端发送附带条件的请求时,服务端允许请求访问资源,但因条件未满足,直接返回 304 Not Modified(服务端资源未改变,可直接使用客户端未过期的缓存)。虽然 304 被划分在 3XX 类别中,但与重定向没有关系
- 307 Temporary Redirect - 临时重定向
4XX 客户端错误
- 400 Bad Request - 请求报文中存在语法错误
- 401 Unauthorized - 表示发送的请求需要有通过 HTTP 认证的认证信息
- 403 Forbidden - 服务器禁止访问请求的资源
- 404 Not Found - 服务器上没有请求的资源
5XX 服务器错误
- 500 Internal Server Error - 服务器在执行请求时出错
- 503 Service Unavailable - 服务器暂时处于超负载或正在停机维护