访问一个网站的全过程
我们几乎每天都在访问各种各样的网站,通过手动输入网址或点击超链接(相当于浏览器自动的输入网址),却很少有人计较从输入网址开始到浏览器呈现页面,计算机都进行了什么工作,看似简单的上网,实际上流程并不简单,其中也蕴含着人类的科技结晶。
网址到底是什么
在正式开始之前先了解一下网址到底是什么。互联网由形式多样的各种资源组成,HTML 文本、CSS 文本、JavaScript 代码和图片等。与现实生活相同,我们拜访某人时需要知道他的门牌号,访问网络资源时也需要知道“门牌号”。资源的门牌号俗称网址,学名叫统一资源定位符(URL,Uniform Resouces Locator)。一个 URL 形式如下:
$$
http://baidu.com/index.html
$$
http:schame 部分,告诉浏览器如何访问资源。
baidu.com:主机地址部分,告诉浏览器访问资源的服务器位置。
index.html:路径部分,说明了资源位于服务器的什么位置。
缓存查找
与人类相同,我们会记住好友的手机号码,浏览器也会记住经常访问的网站的一些信息,利用这些信息可以提升打开网页的速度。当尝试打开网站时,浏览器会先从记忆中查找一些有用的信息,即从缓存中查找有用的资源,可能是网站的实际地址、可能是一张图片、可能是一个文本文件等。如果浏览器的缓存中没有,再查找系统缓存,如果还没有再进一步查找路由器缓存。
Tips:有一套成熟的缓存机制来保证缓存资源的有效性,当服务器中的资源发生变化时,各处的缓存都会失效。这种情况下浏览器会重新向服务器请求该资源。
DNS 解析
如果缓存不足以支持浏览器呈现完整的网页内容,它就会去服务器请求资源。这时候 URL 中的主机地址就起了作用。
与人类不同的是,计算机无法理解自然语言,也就是说形如 baidu.com 这样的主机地址(在 DNS 解析的领域中称其为域名)无法直接访问,在寻址之前需要将其转换成机器语言(服务器的实际 IP 地址),这就是 DNS 解析。比如笔者在写下这段话时百度首页的域名解析结果为 39.156.69.79
。
DNS 解析过程
与普通资源相同,浏览器先查看缓存中是否记录了被解析域名的对应 IP,如果有结束解析。
如果浏览器缓存中没有对应的解析记录,会查找一个叫 host 的无后缀名的本地文件,其中保存了一些域名对应的 IP 地址。如果能在这里查找到结果也会结束解析,没有结果进入下一步。但是 host 文件经常被黑客用于攻击,目前已经很少使用。
依次查找本地域名服务器、根域名服务器和国际顶级域名服务器,这是一个递归的过程,无论在哪个服务器查找到结果都会返回结果给浏览器并结束解析。
负载均衡和污染
DNS 负载均衡:事实上,一个域名很可能对应多个 IP 地址。这是因为大型网站的客户数量大且跨地域广,网站的维护者们提供了不止一台的主机来维持高质量的服务。比如:当一台主机进行一项长耗时的计算任务时,由另一台主机来完成新的访问请求;当一个用户访问网站时,选择离用户物理距离近的主机提供服务。
DNS 污染:DNS 污染(DNS cache pollution), 又称域名服务器缓存投毒(DNS cache poisoning), 是指一些刻意制造的域名服务器数据包, 把域名指往不正确的 IP 地址。DNS 污染是常见的黑客攻击手段,也是防火长城的主要手段之一。
建立 TCP 连接
为了保证客户端和服务器能可靠通信,双方需要通过 TCP(Transmission Control Protocol,传输控制协议) 建立连接,建立 TCP 连接的过程俗称为 “三次握手”。
三次握手:
- 客户端向服务器发送连接建立请求报文。
- 服务器准备好建立连接后向服务器发送请求确认报文。
- 客户端收到请求确认报文后知道服务器已做好建立连接准备,发送确认报文给服务器后双方建立连接。
此处的客户端和服务器分别指用户浏览网页时使用的浏览器和提供网页服务的主机上的程序,使用客户端和服务器两个词是为了符合 TCP 协议的描述。
客户端发送 http 请求
当建立 TCP 连接后,浏览器生成 http 请求报文发送给主机。
http 协议是 Web 应用的基石,客户端和服务器通过 http 协议传输数据,其功能包括但不限于:完成事务处理、进行缓存控制、标记媒体类型等。
http 请求报文一般包含的内容有:协议版本号、目标主机地址、请求资源目录等。
服务器处理请求
网站主机收到来自浏览器的 http 请求报文后,会对其进行解析,并针对客户端的请求内容进行相应的处理。纯静态网页只需返回浏览器需要的资源即可,动态网页需要从其他位置查找到所需的数据并进行页面渲染,处理过后生成 http 响应报文回传给浏览器。
http 响应报文的一般内容有:响应类型、响应描述信息、响应结果等。
浏览器解析网页
当浏览器收到服务器返回的 http 响应报文后,首先解析 http 响应报文,从中提取出所需的资源文件。我们知道一个最基础的网页是由 HTML、CSS 和 JavaScript 文本代码构成的,浏览器解析它们并呈现网页的过程如下:
- 解析 HTML 代码生成 DOM 树。
- 解析 CSS 代码生成 CSSDOM 树。
- 合并 DOM 和 CSSDOM 形成渲染树。
- 根据渲染树计算每个元素在网页中的位置。
- 将各个点绘制到屏幕上。
这五个步骤在不同的浏览器中细节不同,这也导致了一些网站在不同浏览器中的表现略有不同。
对于 JavaScript,浏览器会在其出现的位置就开始解析并执行。通常编写科学的网页会将 JS 代码放置在 </html>
之前、</body> 之后以减少 Bug。JS 解析工作由浏览器内置的 JS 解析引擎完成,不同浏览器的解析引擎也不一定相同,这是导致某些网站只能在特定浏览器上正常工作的主要原因。
保持或释放连接
一个网页通常由很多资源组成(至少一个 HTML 文本、多个 CSS 和 JavaScript 文本、多媒体文件等),为每一个资源都进行一次 TCP 连接肯定是不科学的,在一次 TCP 连接期间传输完一个网页的全部资源会很大的提高网页响应效率。
当 TCP 连接超过一定时间或不再使用时再释放连接。
一篇总结性的学习笔记,很多的内容都是浅尝辄止,其中涉及到的 DNS 、TCP、http、浏览器解析并呈现网页等内容都值得深入学习,后续补坑。