书籍是人类进步的阶梯--高尔基
前言
今天介绍一个简单的话题,你知道当我们在浏览器网页地址栏输入URL时,Web页面是如何呈现的吗?
当然Web页面不可能凭空显示出来,简单来说是Web浏览器根据我们输入的URL地址,向Web服务器获取文件资源然后显示在浏览器上,但是背后其实有这一个非常复杂的过程。像这种通过发送请求获取服务器资源的 Web 浏览器等, 都可称为客户端( client) 。
而客户端和Web服务器端之间通信是使用一种名为 HTTP( HyperText Transfer Protocol, 超文本传输协 议)
的协议作为规范, 只有双方遵循这种规范二者才能通信。比如:两个人说话都用普通话肯定都能听懂,假如其中一个用方言或者都用各自的方言是不是两个人谈话都比较难懂,甚至有的方言根本听不懂。那么下面就来说说HTTP
。
与 HTTP 关系密切的协议
为了理解 HTTP, 我们有必要事先了解一下 TCP/IP
协议族。TCP/IP
是互联网相关的各类协议族的总称,HTTP
协议就是其中的一个子集。而这些协议是计算机与网络设备要相互通信的规则,想要通信双方就必须基于相同的方法。
TCP/IP
的分层管理
TCP/IP
协议族里重要的一点就是分层。 TCP/IP
协议族按层次分别分为以下 4 层: 应用层、 传输层、 网络层和数据链路层。分层的好处就是使得每一层之间都是低耦合,如果某个地方改动只需要改变特定层级的协议,而不必把整体全部换掉,下面的一副图展示了每层的作用:
另外扩展一幅图,上图是通过TCP/IP
的四层模型划分,下面一幅图是通过OSI
的七层模型划分,可以了解一下,很有用:
TCP/IP
通信传输流
现在我们了解到了TCP/IP
协议族的四层模型,我们可以看到HTTP
是属于应用层,也就是说当我们在浏览器上面访问一个网站,利用 TCP/IP
协议族进行网络通信时, 会通过分层顺序与对方进行通信。 发送端从应用层往下走, 接收端则往应用层往上走,具体过程如下图:
负责传输的 IP
协议
IP
协议的作用是把各种数据包传送给对方。 而要保证确实传送到对方那里, 则需要满足各类条件。 其中两个重要的条件是 IP
地址和 MAC地址
IP
地址指明了节点被分配到的地址, MAC 地址是指网卡所属的固定地址。而IP
间的通信依赖 MAC 地址。但是往往通信的双方不在同一个局域网,例如:我们搜索百度,百度肯定不和我们在一个局域网,就需要经过多台计算机和网络设备中转才能连接到百度。 而在进行中转时, 会利用下一站中转设备的 MAC地址来搜索下一个中转目标。 这时, 会采用 ARP 协议( AddressResolution Protocol)
。 ARP
是一种用以解析地址的协议, 根据通信方的 IP
地址就可以反查出对应的 MAC 地址。
确保可靠性的 TCP 协议
按层次分, TCP 位于传输层, 提供可靠的字节流服务。字节流服务为了方便传输, 将大块数据分割成以报文段( segment) 为单位的数据包进行管理。 而且 TCP 协议能够确认数据最终是否送达到对方,保证传输可靠性。而这种可靠性就是TCP 协议采用了三次握手( three-way handshaking) 策略,意思就是用 TCP 协议把数据包送出去后,一定会向对方确认是否成功送达,过程如图所示:
第一次握手:客户端主动发送带有SYN标识的请求,然后处于SYNC_SENT状态,等待服务器确认。(此时客户端不知道服务器接受到了自己发送的请求没有)
第二次握手:服务器接受到客户端发送过来的SYN并且需要发送ACK信息对这个SYN报文段进行确认,同时还要发送自己的SYN请求信息,服务端会把ACK+SYN放在一个报文段发送给客户端,此时处于SYN_RECEIVED状态。(此时服务器端知道客户端有发送的功能,但是不知道自己有没有发送的功能以及客户端有没有接受的功能)
第三次握手:客户端接受到服务端的SYN+ACK(此时客户端知道自己有发送的功能以及服务器的接受功能,但是服务器还不知道自己的接受功能),接着客户端会向服务端发送ACK的确认标识,发送完毕后双方进入Established,(此时服务器端接受到ACK,知道了客户端的接受功能)完成TCP三次握手。
过程梳理:
1.客户端发送请求连接SYN
2.服务端回复确认ACK,并发送自己的SYN(此步骤完成客户端知道自己有发送能力和接受能力,以及服务器端的发送和接受能力。但是服务端只知道客户端发送能力)
3.客户端恢复ACK(此步骤完成服务端知道客户端接受能力)
4.以上步骤完成,客户端和服务端均知道对方的接受和发送能力,即三次握手完毕
负责域名解析的 DNS
服务
DNS( Domain Name System)
服务是和 HTTP 协议一样位于应用层的协议。 它提供域名到 IP
地址之间的解析服务。
还是上述的例子,当我们访问百度的时候是直接通过在浏览器的地址栏输入www.baidu.com
而非输入的是IP
地址,但是在网络连接过程中,真正传输的是IP
地址,而非www.baidu.com
,实则www.baidu.com
是域名,该域名的背后实则就是IP
地址,而我们并没有输入IP
地址,那么传输是如何进行的?此时就需要用到DNS
服务,而DNS
协议就可以提供通过域名查找 IP
地址, 或逆向从 IP
地址反查域名的服务。也就是说我们的输入www.baidu.com
连接访问是先通过DNS
找到对应的IP
地址,然后通过IP
地址进行请求连接。大致过程如下图:
各种协议与 HTTP 协议的关系
通过下图了解下 IP 协议、 TCP 协议和 DNS 服务在使用HTTP 协议的通信过程中各自发挥了哪些作用。
URI 和 URL
-
URI(
Uniform Resource Identifier
):统一资源标识符,URI 用字符串标识某一互联网资源,比如:ftp://ftp.is.co.za/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt
-
URL(
Uniform Resource Locator
):统一资源定位符,URL 表示资源的地点,比如:http://www.baidi.com/
HTTP协议
超文本传输协议(HyperText Transfer Protocol
,简称:HTTP
)是一种通信协议,它允许将超文本标记语言(HTML
)文档从Web服务器传送到客户端的浏览器,HTTP 协议规定, 请求从客户端发出, 最后服务器端响应该请求并返回。 换句话说, 肯定是先从客户端开始建立通信的, 服务器端在没有接收到请求之前不会发送响应。下面是一个具体示例:
下面则是从客户端发送给某个 HTTP 服务器端的请求报文中以及响应报文的内容。
- 请求报文是由请求方法、 请求 URI、 协议版本、 可选的请求首部字段和内容实体构成的。
- 响应报文由协议版本、 状态码( 表示请求成功或失败的数字代码) 、 用以解释状态码的原因短语、 可选的响应首部字段以及实体主体构成。
常用请求HTTP请求方法
请求方法 | 介绍 |
---|---|
GET | 请求获取指定的资源经服务器端解析后返回响应内容 |
POST | 用来传输实体的主体 |
PUT | 从客户端向服务器传送的数据取代指定文档的内容,PUT是幂等的 |
HEAD | 获得报文首部,和 GET 方法一样,但是不返回报文主体部分 |
DELETE | 按请求服务器删除指定的资源 |
OPTIONS | 用来查询针对请求 URI 指定的资源支持的方法 |
TRACE | 回显服务器收到的请求,主要用于诊断或测试,容易引发XST( Cross-Site Tracing, 跨站追踪)攻击 |
CONNECT | 要求在与代理服务器通信时建立隧道, 实现用隧道协议进行 TCP 通信。 主要使用 SSL( Secure Sockets Layer, 安全套接层) 和 TLS( Transport Layer Security, 传输层安全) 协议把通信内容加 密后经网络隧道传输 |
持久连接
下图是一个客户端访问服务端的多次请求示意图:
图中可以看出,客户端每次访问一个资源都需要进行TCP连接和断开连接。而为解决TCP 连接的问题,也就是每次发送一个请求就需要三次握手和四次挥手,于是 HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接( HTTP Persistent Connections, 也称为 HTTP keep-alive 或HTTP connection reuse) 的方法。 持久连接的特点是只要任意一端没有明确提出断开连接, 则保持 TCP 连接状态
持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销, 减轻了服务器端的负载。 另外, 减少开销的那部分时间, 使HTTP 请求和响应能够更早地结束。在 HTTP/1.1 中, 所有的连接默认都是持久连接,
使用 Cookie 的状态管理
HTTP 是无状态协议, 它不对之前发生过的请求和响应的状态进行管理。 也就是说, 无法根据之前的状态进行本次的请求处理。
假设要求登录认证的 Web 页面本身无法进行状态的管理( 不记录已登录的状态) , 那么每次跳转新页面要再次登录, 或者在每次请求报文中附加参数来管理登录状态。
如果每次登录就很不现实,页面折磨多,登录能把人累死。于是引入了 Cookie 技术。 Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息, 通知客户端保存 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
3.请求报文( 自动发送保存着的 Cookie 信息)
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724
相关参考:
图解HTTP