访问一个网址背后的过程?

piter 发布于 1 天前 15 次阅读 6167 字


前言

当我们敲键盘,在浏览器地址栏输入网址(URL),回车访问网站的时候,看似简单的操作,实际背后有很多看不到的网络协议和web渲染协作,信息流传递等众多过程。

我将以时间顺序,从我们从浏览器地址栏输入URL开始,深入讨论一下这个原理


一、URL解析与协议选择

首先,我先就着地址栏URL来讲讲吧,我们以一个典型URL-->https://example.com:443/dir/index.htm?uid=1#ch1 来解析其组成部分:

完整的地址栏URL剖析
图一:完整的地址栏URL剖析
  1. 协议 (https://): 最左侧的部分,指示浏览器应使用何种协议与服务器通信。
    • HTTP (Hypertext Transfer Protocol): 超文本传输协议,是Web内容传输的基础,定义了浏览器与服务器之间的请求和响应格式,是无连接无状态的。
    • HTTPS (Hypertext Transfer Protocol Secure): 即在HTTP之上增加了传输层安全(TLS/SSL)协议进行加密,保障数据传输的机密性、完整性和认证性,是当前Web通信的主流。

我们探讨的是访问网址背后的过程,所以以http(s)协议为主来讲。

举个例子吧,你在网上购物、冲浪,这些操作都是通过HTTP(S)协议进行的。它定义了你的浏览器(客户端)和网站服务器之间如何“对话”,请求什么、回应什么。

  • HTTP: 就像你给服务器写了一封信(请求),服务器收到后回了一封信(响应),告诉你页面内容。它是无状态的,服务器不记得你上一次做了什么。
  • HTTPS: 在HTTP的基础上加了一层安全锁(TLS/SSL加密)。你的“信”在传输过程中会被加密,别人看不懂,保证了你的隐私和数据安全。这也是为什么我们现在访问的网站大多是https开头。

HTTP(S)的沟通方式就像是“你问我答”:浏览器发出请求,服务器给出响应。

  1. 域名 (example.com):方便用户记忆。

  2. 端口号 (:443): 指定服务器上提供服务的特定“通道”数字。

上面图一所示的还有服务器端口号,但是看图例,我们在操作的时候不是很常见了-->域名+端口号。

当然,我们访问地址的时候默认的HTTP对应80端口,而HTTPS对应443端口,那为什么我们访问的时候没有输入过呢?因为这是协议的缺省端口

白话来说就是方便用户,这个缺省端口,约定成俗了,你访问网站就是走80或者443端口。

如果你一定要让用户在输入 URL 的过程中输入端口,又或者要输入个 www等等,用户就要给你扔过来“十万个为什么”了...

为什么要加个 443?
为什么不是 334, 443是啥意思?
为什么一会儿是 80, 一会儿又是 443?
为什么加个 www, 啥意思?
为什么末尾还加个斜杠, 不加会死吗?
...

惹不起, 惹不起...

还记得前面说的, 用户是笨蛋, 用户是懒汉吗?

这里又要引用一句计算机世界的名言了: 程序员和上帝打赌要开发出更大更好连傻瓜都会用的软件, 而上帝却总能创造出更大更傻的傻瓜。目前为止,上帝赢了。
Programmers are in a race with the Universe to create bigger and better idiot-proof programs. The Universe is trying to create bigger and better idiots. So far the Universe is winning.

说句心里话, 很多时候, 用户能记住你的域名就阿弥陀佛了, 你就该烧高香了, 你还想用户记住你的端口, 真的想多了...

另一方面, 说到这里我们应该也能明白了, 那就是理论上,Web 服务实际上可以构建在任何端口之上。比如在本地开发的时候,用户只有你自己,那当然你可以随便挑一个端口,比如 8080,只要自己知道就好了或顶多告诉另一个与你配合的前端同事。

同理, 其它非 Web 的服务, 比如 FTP 服务, 也不一定说非得在 21 端口上等等; MySQL 服务的端口同样可以调整为 3306 之外的端口.

  1. 文件路径 (/dir/index.htm): 请求资源在服务器上的确切位置,服务器文件系统中的目录和文件结构。

  2. 查询字符串 (?uid=1): 以问号?开头,后面是通过键值对形式(如key=value,多对之间用&连接)传递给服务器的额外参数。这些参数常用于动态过滤、搜索、会话管理或传递特定操作指令。

  3. 片段标识符 (#ch1): 以井号#开头,用于标识URL所指向资源内部的某个特定位置(如HTML文档中的一个锚点)。这部分信息不会被发送到服务器,仅由浏览器在接收到完整页面后,用于定位页面内的特定区域。

二、匹配IP和URL:DNS解析

当浏览器解析了URL之后,尽管知道了域名,但是网络设备之间无法直接通过域名进行通信,就好比身份证一样,名字就是域名,当然这并不是很准确,因为身份证的名字是可以重复的,域名还是不行的,但是总而言之,身份证号就是认证的基础,所以我们得到域名之后会进一步服务器的IP地址(如IPv4地址123.45.67.89或IPv6地址2001:db8::1)。这样才能准确把你请求的东西发给你,这个过程就是将域名翻译成IP地址的过程,这就是域名系统(DNS)解析的工作。

IP:
IP也分公网IP内网IP
公网IP(Public IP Address):是可以在互联网上被直接访问的、全球唯一的IP地址。它允许你的设备直接与互联网上的其他设备通信,例如访问网站服务器、远程连接等。每个连接到互联网的设备在外部世界看来都使用一个公网IP地址。
内网IP(Private IP Address):也称为局域网IP,是只在特定局域网内部有效的IP地址,不能直接用于互联网通信。常见的内网IP地址段有:
10.0.0.010.255.255.255
172.16.0.0172.31.255.255
192.168.0.0192.168.255.255
127.0.0.1localhost:这是特殊的回环地址(Loopback Address),指向本机自己,主要用于本地测试和开发,不属于公网或内网IP范畴,但常用于表示本地服务。
192.168.0.1:这是典型的内网IP地址,通常是家庭路由器或局域网内网关的默认地址。

1. 什么是DNS?

DNS (Domain Name System) 是一项位于应用层的协议,被誉为“互联网的电话簿”。它提供了域名到IP地址的映射服务,是互联网得以高效运行的关键基础设施之一。

2.DNS解析流程示例

当你输入域名并回车后,DNS解析通常按以下步骤进行:

  1. 本地查询: 浏览器首先检查自身的DNS缓存。如果未命中,则向操作系统查询本地DNS缓存、hosts文件。
  2. 递归查询: 若本地无记录,操作系统会将请求提交给配置的本地DNS服务器(通常由你的互联网服务提供商ISP或路由器提供)。
  3. 迭代查询: 本地DNS服务器会发起一系列迭代查询:

    • 查询根DNS服务器(负责顶级域名如.com.org)。
    • 根服务器返回相应的顶级域名(TLD)服务器地址。
    • 本地DNS服务器再查询TLD服务器。
    • TLD服务器返回该域名对应的权威域名服务器地址。
    • 本地DNS服务器最后向权威域名服务器查询,权威服务器最终返回所需的IP地址。
    • IP地址逐级返回到浏览器,并被各级缓存起来,以加快下次访问。

    【IP地址与DHCP】

    你的电脑或手机等设备是如何获取到自身IP地址以及它要使用的DNS服务器地址的呢?这通常通过动态主机配置协议(DHCP, Dynamic Host Configuration Protocol)自动完成。当设备连接到网络后,DHCP服务器会为你自动分配必要的网络配置信息(包括IP地址、子网掩码、默认网关以及DNS服务器地址),极大简化了网络管理。

    【常用公共DNS服务器】

    除了ISP提供的DNS,你也可以选择使用公共DNS服务,如Google DNS (8.8.8.8)、Cloudflare DNS (1.1.1.1)、阿里DNS (223.5.5.5)、360DNS等。

    3. DNS安全问题

    ⚠️ 常见威胁

  4. DNS劫持:恶意修改DNS解析结果
  5. DNS污染:返回错误的IP地址
  6. DDoS攻击:大量请求导致服务不可用
  7. 缓存投毒:污染DNS缓存

安全措施

  • DNSSEC(DNS安全扩展)
  • DoH(DNS over HTTPS)
  • DoT(DNS over TLS)

传统的DNS查询是明文传输的,存在被DNS劫持(返回错误IP地址)或DNS污染(返回虚假IP地址)的风险。

自建DoH可以很大程度上避免了DNS劫持以及污染,而且各大运营商会有屏蔽或者间歇性阻断,导致你可能会发现,这个网站,移动不可以访问,联通电信可以。我们一般用的都是运营商的DNS,当然也可以使用阿里云或者360的DNS,Google和Cloudflare的由于网络问题应该是使用不了的,当然可以使用自建的DoH,我用cf的搭建了一个。使用电脑的话,以Edge浏览器为例,可以在这个地方修改。

Edge浏览器DoH设置
图二:Edge浏览器DoH设置

当你在终端ping 域名比如ping baidu.com的时候你就可以看到服务器地址:

ping baidu.com
图三:Ping命令查看服务器IP

大部分情况下没那么简单,通常你得到的是CDN的IP而不是源站IP(如图四),通常是为了安全起见,暴露源站IP的后果就是会导致服务器被DDoS,严重的导致服务崩溃,这里不再赘述。

查ip地理位置
图四:IP地理位置查询示例

三、建立连接:TCP协议的三次握手

浏览器通过DNS获取到服务器的IP地址后,它并不能马上发送HTTP请求。为了确保数据可以可靠和有序地传输,浏览器(作为客户端)和服务器之间需要先建立一个稳定的通信通道。这个通道的建立,由传输层的TCP(传输控制协议)通过“三次握手”来完成。

TCP/IP协议族概览

TCP/IP协议族是互联网的基础,它将复杂的网络通信任务抽象为多个层次(或称为模型)。

我们可以把 TCP/IP 协议族想象成一个多层包裹系统

  • 1. 应用层 (Application Layer):

    • HTTP(S) 就在这里! 还有FTP、SMTP(发邮件)、DNS(域名解析)等。
    • 作用: 它们是直接和应用程序打交道的协议,比如浏览器用HTTP(S)来网页,电子邮件客户端用SMTP来发邮件。
  • 2. 传输层 (Transport Layer):

    • TCP (Transmission Control Protocol 传输控制协议):
      • 特点: 像一个谨慎的快递员,确保你的包裹(数据)安全、完整、按顺序地从一头送到另一头。它会反复确认收到,如果丢了会重发。
      • HTTP(S) 就是依赖TCP来传输数据的!
    • UDP (User Datagram Protocol 用户数据报协议):
      • 特点: 像一个迅速的邮递员,只管把包裹发出,不关心你有没有收到、有没有丢。速度快,但不可靠。
      • 比如在线视频会议、实时游戏,偶尔丢一两个包问题不大,更看重速度。
    • TCP保证靠谱,UDP追求速度。
  • 3. 网络层 (Network Layer):

    • IP (Internet Protocol 网际协议):
      • 特点: 就像包裹上的收发地址(IP地址)。IP协议负责找到最佳路径,把你的包裹(数据包)从起点送到终点,即使经过很多个不同的网络。
      • 它不关心包裹有没有坏,只负责“指路”。在大多数网络环境中,设备的IP地址不是手动配置的,而是通过动态主机配置协议(DHCP, Dynamic Host Configuration Protocol)自动获取的。DHCP是一个客户端/服务器协议,DHCP服务器能够自动为网络中的客户端(如你的电脑、手机)分配IP地址、子网掩码、默认网关以及DNS服务器地址等网络配置信息。这种动态分配方式极大地简化了网络管理,避免了IP地址冲突和手动配置的繁琐。
  • 4. 数据链路层 (Data Link Layer):

    • 特点: 你的数据在这里被封装成“帧”,像是在同一个办公楼层里传递文件。它处理的是相邻设备之间的传输,比如你的电脑和路由器之间。
  • 5. 物理层 (Physical Layer):

    • 特点: 负责把数据转换成电信号、光信号或无线电波,通过网线、光纤或空气进行传输。

TCP三次握手原理:

这个过程就像打电话前互相确认对方是否在线:

TCP三次握手
图四:TCP三次握手示意图
  1. 第一次握手(SYN): 客户端向服务器发送一个SYN(同步)包,表示“我想与你建立连接,我的初始序列号是X”。
  2. 第二次握手(SYN-ACK): 服务器收到SYN包后,如果同意连接,会向客户端发送一个SYN-ACK(同步-确认)包,表示“我收到了你的请求,同意建立连接,我的初始序列号是Y,同时确认收到了你的X(X+1)”。
  3. 第三次握手(ACK): 客户端收到SYN-ACK包后,再向服务器发送一个ACK(确认)包,表示“我收到了你的确认,现在可以开始发送数据了,确认收到了你的Y(Y+1)”。

至此,客户端和服务器之间就建立了一条可靠的双向通信通道。


四、客户端-服务器通信

在TCP连接成功建立之后,浏览器便可以依据HTTP(S)协议的规范,组织并发送请求给服务器,并接收服务器返回的响应。这个过程涉及数据在协议栈中的封装、路由、解封装,以及HTTP/HTTPS协议定义的请求与响应流程。

1. 数据包的封装、传输与解封装

当浏览器发起一个HTTP(S)请求时,数据会从应用层开始,自上而下地通过TCP/IP协议族的各个层进行封装。这个过程可以想象成给信件层层套上信封,每层信封都有自己的信息:

  • 应用层: 浏览器生成包含请求信息(如要获取的网页内容、提交的数据)的HTTP(S)报文。如果是HTTPS,内容会在此阶段被加密
  • 传输层: HTTP(S)报文被TCP协议分割成小段,并添加TCP头部(包含端口号、序号等,确保可靠传输)
  • 网络层: TCP报文段被IP协议加上IP头部(包含源IP和目标IP),形成IP数据包,负责在互联网中寻址
  • 数据链路层: IP数据包再被加上帧头部(包含MAC地址等),形成数据帧,用于在相邻设备间传输
  • 物理层: 数据帧最终被转换为电信号(或光信号、无线电波),通过物理媒介发送出去

封装后的数据包从客户端发出,经过你家或公司的路由器(默认网关),再通过互联网中无数个路由器(路由与转发),最终抵达目标服务器。每经过一个路由器,数据包的IP头部信息会被读取,用于决定下一跳的路径。

NAT(网络地址转换)

大多数家庭和企业网络中,多个内部设备通过一个路由器共享同一个公网IP地址访问互联网。这个路由器通过网络地址转换(NAT)技术实现:当内网数据包发出时,路由器会将其源私有IP和端口转换为自己的公网IP和新端口;当外部响应数据包返回时,路由器再通过NAT表将数据包重新映射回内网正确的设备。这解决了IPv4地址紧缺问题,同时也增强了内网安全性,当然现在的几乎每个终端都有唯一的IPV6地址。

2.HTTP/HTTPS 请求与响应

HTTP/HTTPS处在应用层,具体的通信内容就是由HTTP请求HTTP响应构成的:

  • HTTP 请求: 浏览器向服务器发送的文本信息,通常包括:
    • 请求行: HTTP方法(如GET、POST、PUT、DELETE)、请求资源的统一资源标识符(URI)、HTTP协议版本。
    • 请求头: 附加信息,如User-Agent(客户端浏览器类型)、Accept(客户端可接受的内容类型)、Cookie(客户端保存的会话信息)、Referer(来源页面)等。
    • 请求体: 在POST等方法中,包含发送给服务器的数据(如表单提交的用户输入)。
  • HTTP 响应: 服务器对浏览器请求的回复,通常包括:
    • 状态行: HTTP协议版本、状态码(如200 OK表示成功,404 Not Found表示资源未找到,500 Internal Server Error表示服务器内部错误)、状态描述。
    • 响应头: 附加信息,如Content-Type(响应内容的媒体类型,如text/htmlimage/jpeg)、Set-Cookie(服务器设置的Cookie)、Cache-Control(缓存策略)等。
    • 响应体: 实际返回的内容,如HTML文档、CSS样式表、JavaScript代码、图片等资源的数据流。

以postman为例,可以看到我以bing.com为例,发送GET请求,得到了200OK以及响应

还有更详细的信息


五、从数据到像素:关键渲染路径 (Critical Rendering Path)

浏览器接收到服务器返回的HTML、CSS、JavaScript等资源后,并不会立即将其显示在屏幕上。它需要经过一系列内部处理步骤,将这些原始数据转化为用户可见的像素。这个过程被称为“关键渲染路径(Critical Rendering Path, CRP)”。

  1. 构建DOM树 (Document Object Model):

    • 浏览器解析HTML响应体,将其转换为一个内存中的树状结构,即文档对象模型(DOM)树。DOM树完整地表示了HTML文档的结构、内容及其元素之间的关系。
  2. 构建CSSOM树 (CSS Object Model):

    • 同时,浏览器解析HTML中引用的所有CSS代码(包括<style>标签内的样式、<link>引用的外部样式表、以及元素内联样式),构建出CSS对象模型(CSSOM)树。CSSOM包含了所有样式规则,并按特定优先级(层叠、继承等)组织起来。
  3. JavaScript编译和执行:

    • 当HTML解析器遇到<script>标签时,它通常会暂停HTML的解析,优先下载、解析、编译并执行JavaScript代码。这是因为JavaScript可能动态修改DOM结构或CSSOM样式。asyncdefer属性可以改变这种阻塞行为。

    【JavaScript水合(Hydration)】

    在使用现代前端框架(如React、Vue)的服务器端渲染(SSR)应用中,服务器会先生成HTML发送给浏览器。浏览器接收后,可以立即展示这个静态HTML(首屏渲染)。但此时页面通常还不具备交互性。当JavaScript代码下载并执行完毕后,框架会将其“连接”到已有的HTML结构上,使其变得可交互(例如绑定事件监听器),这个过程就叫“水合”。水合确保了页面的快速显示与后续的完整交互体验。

  4. 构建渲染树 (Render Tree):

    • 浏览器将DOM树和CSSOM树结合,创建一个渲染树(也称为渲染对象树或布局树)。渲染树只包含页面中可见的元素。例如,head标签的内容和设置了display: none;的元素将不会被包含在渲染树中。渲染树的每个节点都包含了元素在页面上的最终样式信息。
  5. 布局 (Layout / Reflow):

    • 渲染树构建完成后,浏览器开始计算渲染树中每个可见元素在设备视口内的确切位置和大小。这个过程称为“布局”或“回流”(Reflow)。每次DOM结构或样式的改变导致元素尺寸、位置、或相邻元素几何属性发生变化时,都可能触发回流。
  6. 绘制 (Paint):

    • 布局完成后,浏览器根据渲染树的节点以及其计算出的样式和布局信息,将页面内容逐层绘制到屏幕上。这个过程包括绘制文本、背景、边框、图片、阴影等所有可见的像素。现代浏览器通常会将页面分解为多个图层进行绘制。
  7. 合成 (Compositing):

    • 最后,如果页面被分解为多个绘制层,浏览器会将这些独立的图层组合(合成)在一起,形成最终的屏幕图像。这个过程通常利用GPU加速,高效地将不同图层按照正确的顺序叠加显示,比如处理CSS的transformopacity等属性。

至此,一个完整的网页内容就已经从网络请求数据,成功转化为用户屏幕上的视觉呈现。


八、TCP四次挥手:结束连接

最后是四次挥手。

当所有内容加载完毕,用户浏览结束,或者关闭了网页,客户端和服务器之间的通信不再需要维持时,为了安全、有序地终止TCP连接,会执行一个“四次挥手”的过程。这确保了双方都有机会发送完所有的数据。

TCP四次挥手原理:

四次挥手
图六:TCP四次挥手示意图
  1. 第一次挥手(FIN): 客户端(或任何一方,此处以客户端为例)发送一个FIN(结束)包,并设置FIN标志位为1,表示客户端已没有数据要发送了,请求关闭连接。
  2. 第二次挥手(ACK): 服务器收到FIN包后,发送一个ACK(确认)包,确认收到客户端的关闭请求。此时,服务器可能还有未发送的数据,它可以继续发送数据。
  3. 第三次挥手(FIN): 当服务器的数据也发送完毕后,它也会发送一个FIN包给客户端,表示它也没有数据要发送了,请求关闭连接。
  4. 第四次挥手(ACK): 客户端收到服务器的FIN包后,再发送一个ACK包确认。客户端会进入TIME_WAIT状态,等待一段时间,确保服务器收到了最后一个ACK,然后彻底关闭连接。

通过这四次交互,TCP连接被安全、完整地终止,释放了双方的资源。


参考文献

  1. 《图解HTTP》 - [日] 上野 宣
  2. URL协议与格式详解-CSDN博客
  3. 深入理解什么是端口(port)
  4. DNS的作用是什么?为什么一定要配置DNS才能上网-CSDN博客
  5. 一文搞懂TCP的三次握手和四次挥手-云社区-华为云
  6. 只需三分钟!读懂DHCP的原理与配置
  7. What is DHCP Server in Windows Server? | Microsoft Learn
  8. How browsers work - An overview of how a modern web browser renders a webpage
  • reward_image1
永远不要因为需要大量时间才能完成,就放弃梦想,时间怎么样都会过去的
最后更新于 2025-08-15