1 简介
HTTP(Hypertext Transfer Protocol) 超文本传输协议,是万维网的基础,在浏览器中我们主要是用 HTTP 以及 HTTPS 进行网络访问,那么我们在浏览器的地址栏输入一个 URL到回车展示给我们页面的过程发生了什么呢?
2 URL 介绍
假设众所周和,互联网的资源是由 URL 定位让我们访问的,URL 就是统一资源定位符。一般我们访问 baidu.com
,就可以访问到百度的首页,最后访问的实际完整地址是 https://www.baidu.com:443
完整的 URL 构成如下:
https://www.baidu.com:443/test/demo.html?name=lilei&age=23/#hi
模式协议(https) + 域名部分(www.baidu.com) + 端口部分(443) + 虚拟目录(/test) + 文件名部分(/demo.html) + 参数部分(?name=lilei&age=23) + 锚点部分(#hi)
3 DNS 查找
以 chrome 浏览器为例,当输入 baidu.com
的时候,我们实际访问的是 14.215.177.39
,这是百度的 IP 地址,从 baidu.com
到 14.215.177.39
的过程就是一个 DNS 解析的过程。
首先会从浏览器里 DNS 缓存查找,chrome://dns/
,一旦查找到了就完成了这个解析过程,但是如果没有呢? 那么接着会从电脑本地的 hosts 文件中查找,以下为 windows 的 hosts 文件,最后一行是我加的。
- # Copyright (c) 1993-2009 Microsoft Corp.
- #
- # This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
- #
- # This file contains the mappings of IP addresses to host names. Each
- # entry should be kept on an individual line. The IP address should
- # be placed in the first column followed by the corresponding host name.
- # The IP address and the host name should be separated by at least one
- # space.
- #
- # Additionally, comments (such as these) may be inserted on individual
- # lines or following the machine name denoted by a '#' symbol.
- #
- # For example:
- #
- # 102.54.94.97 rhino.acme.com # source server
- # 38.25.63.10 x.acme.com # x client host
-
- # localhost name resolution is handled within DNS itself.
- # 127.0.0.1 localhost
- # ::1 localhost
- 14.215.177.39 baidu.com // 这里为例子演示
- 复制代码
可以在这里改变这个 IP 地址,那么就访问不到百度首页了。像最简单的科学上 google 的方法就可以通过修改 hosts 文件达到这个效果。
一般 hosts 文件是没有这个解析地址的,于是只能接着向上查找运营商的解析,例如电信联通移动以及著名的114。像这里,有时候手机浏览器访问网页会出现奇奇怪怪的广告,那么很大可能是运营商 DNS 劫持,可以通过手动设置 DNS (例如 114.114.114.114) 避免。
到此,DNS 查找过程就完成了,得到了域名对应的 IP 地址。
4 互联网协议
在介绍接下来的三次握手之前先简单了解一下计算网络协议,在分层中有4层 5层 7层等之分,我们这里按 5 层来分析。
注: 该部分下主要内容和部分图片来自阮一峰老师的博客和图解HTTP
- 应用层
- 传输层
- 网络层
- 链路层
- 实体层
以下省去了实体层
4.1 实体层
比较简单,就是我们常见的光缆、电缆、无限电波等等物理连接。
4.2 链路层
位于实体层的上方,确定了 0 1 的分组方式。
4.2.1 以太网协议
以太网规定一组电信号构成一个数据包,叫做“帧”,每一帧分成两个部分:标头(head)和数据(data)。 标头说明数据包的发送者、接受者,数据类型等等,而数据则是数据包的具体内容。
4.2.2 Mac 地址
以太网数据包的标头规定了发送者和接受者,那么是如何确定的呢?这里就引入了 Mac 地址的概念。
以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了一对一的能力。
4.2.3 广播
上面的情形只是理论上一个 Mac 地址对接另一个 Mac 地址,这一次真的众所周知,互联网千千万,不可能只存在两个 Mac 地址,那么需要对接的 Mac 地址是如何识别对方的呢?
方法很原始,通过 ARP 协议,向本网络内的所有计算机发送,接受方通过标头来与自身 Mac 地址比较,如果一致就接受并处理,否则则抛弃。
通过以太网协议、Mac 地址、广播,链路层就实现了在同一网络内的多计算机通信。
4.3 网络层
在链路层中,可以实现同一网络内的多计算机通信,理论上是可以实现全网络通信的,但是由于广播的局限性会导致不在同一子网络下的计算机无法通信,且每个计算机”人手一包“的效率也是低下的。于是网络层引入一套新的地址,使我们能区分不同计算机是否属于同一网络,这个就叫做网络地址,简称”网址“。
于是到网络层,计算机有了两个地址。一个是 Mac 地址,一个是网络地址。前者是绑定网卡上的,用于接受子网络下广播的数据包,而后者是管理员分配。处理顺序也是后者先于前者,毕竟要先知道你在哪个省再在哪个市。
4.3.1 IP 协议
网络地址也不是随便定义的,遵循 IP 协议,这个网络地址也叫做 IP 地址。
目前广泛使用的是 IPV4,这版规定网络地址由 32 个二进制位组成。
例如百度的 IP 地址: 14.215.177.39
二进制为: 00001110.11010111.10110001.00100111
一般都是使用十进制来描述,从 0.0.0.0 - 255.255.255.255
IP 地址前部分代表网络,后部分代表主机,假如百度地址的网络部分是前 24 位,也就是 14.215.177
,那么主机部分就是后面的 39,处于同一个网络下的计算机,网络部分是相同的。
但是上面是举例,实际上从 IP 地址并不能看出网络部分是前 24 位还是 前 16 位,没想到吧,哈哈哈。但是可以通过子网掩码来判别。
子网掩码:表示网络特征的一个参数,形式上等于 IP 地址,如果已知百度 IP 地址的网络部分是前 24 位,那么他的子网掩码的网络部分都是 1,主机都是 0,也就是 11111111.11111111.11111111.00000000
,换成十进制就是 255.255.255.0
。
如何通过子网掩码来确定两台计算机是否处于同一子网络呢?答案就是通过将两个 IP 地址与子网掩码进行 AND(&) 运算,如果两个结果一样,则确定就在同一网络。
- 例: 已知下面两个 IP 地址的网络部分是前 24 位,请计算 14.215.177.39 与 14.215.177.255 是否处在同一子网络下。
- 解: 由已知条件可得网络部分为 14.215.177
- 14.215.177.39 和 14.215.177.255 子网掩码的二进制为 11111111.11111111.11111111.00000000
- 14.215.177.39 的二进制为 00001110.11010111.10110001.00100111
- 14.215.177.255 的二进制为 00001110.11010111.10110001.11111111
- 00001110.11010111.10110001.00100111 & 11111111.11111111.11111111.00000000 = 00001110.11010111.10110001.00000000
- 00001110.11010111.10110001.11111111 & 11111111.11111111.11111111.00000000 = 00001110.11010111.10110001.00000000
- 答: 结果一致,所以 14.215.177.39 与 14.215.177.255 处在同一子网络下。
- 复制代码
IP 协议主要就是给计算机分配 IP 地址,确定哪些计算机在同一子网络下。
4.3.2 IP 数据包
IP 数据包与以太网数据包结构类似,IP 数据包以标头+数据包的形式保存在以太网数据包的数据部分。
4.3.3 ARP 协议
在之前链路层我们有提到 ARP 协议,通过该协议向子网络内的所有计算机发送广播。
ARP 协议也是发送一个数据包,包含在以太网数据包中,其中包含了它要查询的主机的 IP 地址,在接收方的 Mac 地址填的是 FF:FF:FF:FF:FF:FF,表示这是一个"广播"地址。然后接受方全部会接受这个广播,取出其中的 IP 地址与自身比较,得出结果。
这里需要补充的是如果两个主机不在同一个子网络,那么需要引入“网关(gateway)”来进行数据包的操作。
4.4 传输层
在 IP 地址 和 Mac 地址的协助下,我们的计算机可以实现全网络下通信了,但是如何区分不同的网络请求呢,也就是说当接受一个数据包,如何分辨它是网页内容还是聊天内容,这时候需要一个叫做“端口”的参数来确定使用这个数据包的程序(进程)。端口是 0 到 65535 之间的整数,0-1023 之间的被系统占用,例如网页访问的通常都是 80 端口,一旦通过 SSL 加密,那么也就是 HTTPS 访问,端口会使用 443 端口,这也就是我们之前访问 baidu.com
实际上访问的是 https://www.baidu.com:443
的结果。
网络层实现了主机到主机的通信,而传输层是建立端口到端口的通信,因此 Unix 系统把主机+端口叫做套接字(socket)。
4.4.1 UDP 协议
通过上面的部分,我们知道端口到端口的通信其实也是需要确定的,那么 UDP 协议就是加上了端口信息的数据包。标头定义了发出端口和接收端口,数据部分就是具体的内容,该数据包存储在 IP 数据包中。
4.4.2 TCP 协议
UDP 协议的有点是简单易实现,但是缺点就是无法确定对方是否接收到了。为了解决这个问题,TCP 协议诞生了,简单理解,TCP 协议就是带有必须确认功能的 UDP 协议。每发出一个数据包都需要得到对方的确认,一旦得不到哪个数据包的确认,就知道需要重发这个数据包了。
4.5 应用层
数据来源五花八门,应用层就是规定程序的数据格式。
TCP 协议可以为各种各样的程序传递数据,比如 Email、WWW、FTP 等等。那么,必须有不同协议规定电子邮件、网页、FTP 数据的格式,这些应用程序协议就构成了"应用层"。
最后的状态就变成了这样
5 三次握手
当了解了互联网协议后,我们接着之前的 URL 访问过程,获得了服务器 IP 地址以后,我们需要进行通信,这会进行一次连接,这是通过 TCP 协议完成的。
三次握手:
第一次由客户端发送 SYN 包到服务器,等待服务器确认;
第二次是服务器接收到 SYN 数据包,将 SYN + 自己发送的 ACK 包一同发送给客户端;
第三次是客户端接收到服务器发送过来的 SYN + ACK 数据包后,再向服务器发送确认包 ACK,客户端和服务器进入连接状态,完成三次握手。
6 HTTP 通信
当客户端和服务器进入连接状态后,那么就可以进行 HTTP(应用层) 的通信了。
完整的 HTTP 请求包含了起始行,请求头,请求体三部分,常见的请求方法有 GET 和 POST。
完成了 HTTP 通信,浏览器接收到服务器的响应,该响应是一个封装了 HTTP 报文的 Response 对象,主要包括状态码,响应头,响应体三部分。
常见的状态码有:
- 1XX: 指示信息,表示请求已接受,继续处理;
- 2XX: 成功,表示请求已接受,已处理。常见的是 200;
- 3XX:重定向,要完成请求必须进行更进一步地操作。例如常见的有 301 永久重定向和 302 临时重定向。302 重定向的网站会保留原有的网址,而影响搜索引擎的抓取;
- 4XX:客户端错误,请求有语法错误或请求无法实现。常见的有 400 错误,前后端协议字段不一致;403错误,表示资源不可用,访问被禁止;404 错误,资源不存在;
- 5XX:服务端错误,无法响应客户端请求。
6.1 HTTPS
随着互联网的普及,人们对安全的重视也与日俱增,HTTP 协议没有办法确认通信方,有可能在传输过程中遭到篡改而不知。此时 HTTPS 出现了,它在 HTTP 上再加入加密处理和认证机制,HTTPS 是披着 SSL 外壳的 HTTP。
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。
在 WEB 配置 HTTPS 的过程中,有一个叫做证书的东西,要理解证书,我们就得先了解一下 HTTPS 的加密解密过程,HTTPS 采用的是混合加密机制。
6.1.1 加密与解密
HTTPS 采用共享秘钥加密和公开秘钥加密两者混用。
共享秘钥加密:使用一对非对称的秘钥。一把叫做私有秘钥,一把叫做公有秘钥。发送方使用公有秘钥加密信息,接收方使用私有秘钥进行解密。
公开秘钥加密:发送方和接收方使用同一把秘钥进行加密。但是被第三者获得秘钥后可以肆意妄为。
为了证实公开密钥的“正统性”,我们听说过的证书闪亮登场。通过数字证书认证机构(CA)颁布的公开秘钥证书,可以确定申请者的身份并对已申请的公开密钥进行签名,然后分配这个公开秘钥,并将这个公开秘钥放入公钥证书后绑定一起。服务器会将这份数字证书发送给客户端,以便进行公开秘钥加密通信。
查看客户端证书
6.1.2 通信
在以上流程中,应用层发送数据时会附加一种叫做“Mac”的报文摘要,它能确定报文是否遭到篡改从而保证了报文的完整性。
6.1.3 小结
整个 HTTPS 通信过程
HTTPS 是使用 SSL 和 TLS 这两个协议的,由于在通信过程中需要加密和解密,所以与 HTTP 相比,HTTPS 的速度会慢 2-100 倍,虽然可以用 SSL 专用加速服务器来改善一下,但是仍然没有根本性的解决方法。
7 页面渲染
当浏览器接受到响应报文,举例是 html 文件,就开始解析和渲染并呈现给用户也就是我们。 一个完整的 html 文件包括了 html 部分,css 部分,javascript 部分。
浏览器对 html 文件的解析是逐行的,于是当读取到外部链接的 css 或者 javascript 或者图片时会重复 http 请求的过程,这也是前端性能优化的一个地方。
浏览器会将 html 解析成一个 DOM 树,将 css 解析成 css rule 树,然后根据 DOM 树和 css rule 树来构造 render 树,之后就计算各节点应处的位置,接下来就是遍历 render 树来绘制每个节点。
其中涉及 DOM 树的结构变化以及几何属性的变化会导致页面重新渲染,这就是所谓的回流;而外观背景色等的操作不会引发布局变化导致重新渲染,这就是重绘。在前端开发中应当尽力避免回流来优化性能。 最后,一个完整的页面就展现在了我们面前。
8 总结
简(tai)而(chang)言(bu)之(kan),在浏览器输入 URL 后,会通过 DNS查找得到这个域名所在的 IP 地址,通过 IP 地址以及 TCP 协议三次握手请求服务器获得资源后,浏览器对资源进行解析并渲染获得最后的结果。