从输入URL到Web页面呈现的全过程

news2024/11/20 1:24:08

当用户在浏览器的地址栏中输入 URL 并点击回车后,页面是如何呈现的。

简单来说,当用户在浏览器的地址栏中输入 URL 并点击回车后,浏览器从服务端获取资源,然后将内容显示在页面上。这个过程经过了:浏览器缓存 -> DNS 域名解析 -> URL 编码 -> 使用 HTTP 或者使用 HTTPS 协议发送请求 ->

  • 对于访问静态资源的 HTTP 请求:CDN -> CDN 回源到对象存储 OSS 或者源服务器
  • 对于访问动态资源的 HTTP 请求:负载均衡器 Nginx -> 应用服务器【API 网关(Zuul、GateWay 等)-> 内部服务(微服务,Controller、Service、DAO)】-> 缓存系统(Redis、EhCache 等) -> 存储系统(MySQL、PostgreSQL、MongoDB 等)

为了减少响应时间,整个过程中的几乎每一个环节都会有缓存。

为了提高系统的可用性、性能,整个过程中的很多环节都需要部署多节点。

浏览器

当用户在浏览器的地址栏中输入 URL 并点击回车后,首先由浏览器进行处理。

浏览器缓存

当用户在浏览器的地址栏中输入 URL 并点击回车后,浏览器会查看自己是否缓存了该资源。

  • 如果浏览器缓存了该资源,并且缓存未过期,那么直接从缓存中获取资源,不向服务端发送请求(命中强缓存)。
  • 如果浏览器缓存了该资源,但是缓存已经过期了,那么浏览器向服务端发送条件请求。服务端会根据条件请求首部字段(If-Match、If-Modified-Since 等)来判断是否命中协商缓存。
    • 如果命中了协商缓存,那么服务端会返回 304 状态码(Not Modified),而不返回浏览器请求的资源。告诉浏览器可以直接用浏览器缓存中的资源。
    • 如果没有命中协商缓存,那么服务器返回浏览器请求的资源。

DNS 域名解析

当用户在浏览器的地址栏中输入 URL 并点击回车后,浏览器要判断 URL 中的是 IP 地址,还是域名。如果 URL 中的是域名,那么首先要做的就是域名解析。

域名解析的过程:首先是浏览器查看浏览器的缓存。如果浏览器中没有该域名的缓存,那么浏览器询问【本地 DNS 解析器】,【本地 DNS 解析器】首先查看本地 DNS 缓存。如果本地 DNS 缓存中没有该域名的缓存,那么【本地 DNS 解析器】请求【本地 DNS 服务器】进行域名解析。如果【本地 DNS 服务器】中没有该域名的缓存,那么【本地 DNS 服务器】向 DNS 系统中的其他远程 DNS 服务器发送查询请求。

  • 如果域名解析失败,浏览器会展示一个报错页面,提示域名不存在。
  • 如果域名解析成功,浏览器就获取到一个域名对应的 IP 地址。

image-20230304144731488.png

以【本地 DNS 解析器】请求【本地 DNS 服务器】进行 www.CDNbook.com 域名的解析为例:

(1)【本地 DNS 解析器】向【本地 DNS 服务器】发送域名解析请求。(8)【本地 DNS 解析器】收到来自【本地 DNS 服务器】的应答。

(2)【本地 DNS 服务器】向【根 DNS 服务器】发送域名解析请求,【根 DNS 服务器】返回 .com 顶级域的域名服务器列表(多条 NS 记录)。

(4)【本地 DNS 服务器】收到应答后,在 .com 顶级域的域名服务器列表中选择一个 IP 地址,向这个 IP 地址对应的 DNS 服务器发送域名解析请求,.com 顶级域的域名服务器返回 CDNbook.com 域的域名服务器列表。

(6)【本地 DNS 服务器】收到应答后,在 CDNbook.com 域的域名服务器列表中选择一个 IP 地址,向这个 IP 地址对应的 DNS 服务器发送域名解析请求,CDNbook.com 域的域名服务器返回 www.CDNbook.com 域的 A 记录列表(多个 IP 地址)。

(8)【本地 DNS 服务器】收到应答后,在 www.CDNbook.com 域的 A 记录列表中选择一个 IP 地址,将该 IP 地址返回给【本地 DNS 解析器】。

(9)浏览器获取到域名对应的 IP 地址,这个 IP 地址可能是 CDN 服务器的 IP 地址,也可能是源服务器的 IP 地址。无论是什么服务器的 IP 地址,浏览器都会向这个服务器发送请求,服务器将用户请求的内容返回给浏览器。

URL 编码

URL 编码也被称为百分号编码。

URL 编码的作用是:在 URL 中,使用 “安全的字符”(允许出现的字符、无歧义的字符) 替换 “不安全的字符”(不允许出现的字符、有歧义的字符)

  • 将 “非 ASCII 字符” 编码为 “ASCII 字符”,便于在 URL 中传输非 ASCII 字符。(URL 中只能出现 ASCII 字符,不能出现非 ASCII 字符)
  • 将 “空格” 编码为 “%20”,便于在 URL 中传输空格。(URL 中不能出现空格)
  • 将 “没有表示特殊含义的保留字符” 进行 URL 编码。(URL 中多个查询参数之间用 & 符号分隔。如果参数值中包含了 & 字符,那么会对 URL 解析造成影响,因此需要对造成歧义的 & 符号进行编码)

URL 编码的规则:简单来说,如果需要对一个字符进行 URL 编码,首先需要判断该字符是否是 ASCII 字符:

  • 如果一个字符是 ASCII 字符,那么对该字符进行 URL 编码,首先需要把该字符的 ASCII 的值表示为两个 16 进制的数字,然后在其前面放置转义字符 %,就得到了该字符的 URL 编码结果。

  • 如果一个字符是非 ASCII 字符,那么对该字符进行 URL 编码,首先需要使用指定的字符编码方式(建议使用 UTF-8 字符编码),将 “非 ASCII 字符” 编码为字节序列(字节序列即二进制数据);然后对其字节序列进行 URL 编码。URL 编码 “二进制数据”,首先需要把 “二进制数据” 表示为 8 位组的序列,将每个 8 位组表示为两个 16 进制的数字,然后在其前面放置转义字符 %,就得到了 “二进制数据” 的 URL 编码结果。

HTTPS 通信

浏览器使用 HTTP 或者使用 HTTPS 协议和服务器通信。

使用 HTTPS 协议通信,通信的双方会先建立 TCP 连接,然后执行 TLS 握手,之后就可以在安全的通信环境里发送 HTTP 报文了。

982510795a50e4b18808eed81dac647c.png

TCP 握手

2286877-20220424192945060-744932028.png

一开始,客户端和服务端都处于 close 状态。

先是服务端监听某个端口,此时服务端处于 listen 状态。

这个时候客户端就可以发送连接请求报文了。


第一次握手

客户端会主动发送连接请求报文,随机初始化序列号为 x,并把 SYN 标志位设置为 1,表示 SYN 报文。

客户端发送 SYN 报文后,客户端进入 syn_sent 状态。


第二次握手

服务端收到 SYN 报文后,服务端会发送 SYN-ACK 报文,用于对客户端发送的 SYN 报文进行应答。

服务端会随机初始化序列号为 y,确认序列号设置为 x + 1,并把 SYN 标志位、ACK 标志位设置为 1。

服务端发送 SYN-ACK 报文后,服务端进入 syn_receive 状态。


第三次握手

客户端收到 SYN-ACK 报文后,客户端会发送 ACK 报文,用于对服务端发送的报文进行应答。

客户端会将序列号设置为 x + 1,确认序列号设置为 y + 1,ACK 标志位设置为 1。

客户端发送 ACK 报文后,客户端处于 established 状态。

当服务端收到 ACK 报文后,服务端进入 established 状态。


此时 TCP 连接就建立完成了,客户端和服务端就可以相互发送数据了。

TLS 握手

TLS 握手过程的简要描述:通信的双方在 TLS 握手的过程中协商 TLS 的版本号、密码套件,交换随机数、数字证书和密钥参数,最终通信的双方协商得到会话密钥。(“Hello” 消息交换随机数,“Key Exchange” 消息交换 “Pre Master Secret”)

  • 浏览器给服务器发送 “Client Hello” 消息,服务器给浏览器发送 “Server Hello” 消息。通信的双方协商 TLS 的版本号、密码套件,并交换随机数。
  • 交换数字证书:服务器为了向浏览器证明自己的身份,服务器给浏览器发送 “server Certificate” 消息,以发送数字证书链,其中包含了两个证书。一个是 CA 机构颁发的数字证书,另一个是 CA 机构的数字证书。
  • 服务器给浏览器发送 “Server Key Exchange” 消息,浏览器给服务器发送 “Client Key Exchange” 消息。通信的双方交换密钥参数(Client Params 和 Server Params),然后通信的双方就用 ECDHE 算法算出 “Pre Master Secret”。
  • 通信的双方根据自己已知的参数(Client Random、Server Random 和 Pre Master Secret)算出主密钥 “Master Secret”,并使用主密钥拓展出更多的密钥(会话密钥),避免只用一个密钥带来的安全隐患。
  • 浏览器给服务器发送 “Change Cipher Spec” 消息,服务器也给浏览器发送 “Change Cipher Spec” 消息。告诉对方:后续传输的都是对称密钥加密的密文。
  • 浏览器给服务器发送 “Finished” 消息,服务器也给浏览器发送 “Finished” 消息。通信的双方把之前发送的数据做个摘要,再用对称密钥加密一下,让对方做个验证。
  • 双方都验证成功,握手正式结束,之后就可以正常收发被加密的 HTTP 请求和响应了。

69493b53f1b1d540acf886ebf021a26c.png

TCP / IP 模型的通信

image-20221202104621528.png

发送数据包

当用户在浏览器的地址栏中输入 URL 并点击回车后,首先由浏览器进行处理,这些处理相当于应用层功能。浏览器处理完成以后,浏览器依据 HTTP 规范构建报文,并将 HTTP 报文发送给传输层的 TCP。

TCP 模块的处理:TCP 根据浏览器的指示,负责建立连接、发送数据以及断开连接。TCP 在浏览器发送过来的数据前端再加上自己的 TCP 首部,随后将附加了 TCP 首部的包再发送给网络层的 IP。

IP 模块的处理:IP 将 TCP 传过来的 TCP 首部和 TCP 数据合起来当做自己的数据,并在 TCP 首部的前端再加上自己的 IP 首部。IP 包生成后,参考路由控制表决定接受此 IP 包的路由器 或 主机。随后,IP 包将被发送给连接这些路由器 或 主机网络接口的驱动程序,以实现真正的发送数据。

如果尚不知道接收端的物理地址(MAC 地址),可以利用 ARP(Address Resolution Protocol) 通过 IP 地址查找物理地址(MAC地址)。

只要知道了对端的物理地址(MAC 地址),就可以将 MAC 地址和 IP 地址交给以太网的驱动程序,以实现真正的发送数据。

网络接口(以太网驱动) 的处理:以太网的驱动程序将 IP 传过来的 IP 首部和 IP 数据合起来当做自己的数据,并在 IP 首部的前端再加上自己的以太网首部。以太网数据包将通过物理层传输给接收端。

接收数据包

网络接口(以太网驱动) 的处理:主机收到以太网包以后,首先从以太网的包首部找到物理地址(MAC 地址)。主机根据物理地址(MAC 地址),判断是否为发给自己的包。

  • 如果接收到的不是发给自己的包,那么主机丢弃数据。
  • 如果接收到的恰好是发给自己的包,那么主机接收数据并查找以太网包首部中的类型域(类型域记录上一层的协议类型),从而确定将数据传给哪个处理程序。
    • 如果上一层协议是 IP,那么就将数据传给处理 IP 的程序;
    • 如果上一层协议是 ARP,那么就将数据传给处理 ARP 的程序;
    • 如果以太网包首部的类型域包含了一个无法识别的协议类型,那么主机丢弃数据。

IP 模块的处理:IP 模块收到 IP 包首部及后面的数据部分以后,也做和以太网驱动类似的处理。

  • 如果判断得出包首部中的 IP 地址与自己的 IP 地址匹配,那么就接收数据并查找 IP 包首部中的类型域(类型域记录上一层的协议类型),从而确定将数据传给哪个处理程序。
    • 如果上一层协议是 TCP,那么就将数据传给处理 TCP 的程序;
    • 如果上一层协议是 UDP,那么就将数据传给处理 UDP 的程序。

对于有路由器的情况下,接收端的 IP 地址往往不是自己的 IP 地址,此时需要借助路由控制表,在查找到应该送达的主机 或 路由器以后再转发数据。


TCP 模块的处理:TCP 模块收到 TCP 包首部及后面的数据部分以后,首先会计算一下校验和,判断数据是否被破坏。然后检查是否在按照序号接收数据。最后检查端口号,从而确定将数据传给哪个具体的应用程序。

TCP 模块接收数据完毕后,接收端给发送端发送一个 “确认(ACK)”。如果发送端没有收到这个确认信息,那么发送端会认为接收端没有接收到数据,然后发送端会一直反复发送。

数据被完整地接收以后,会传给由端口号识别的应用程序。


应用程序的处理:接收端应用程序会直接接收发送端发送的数据。服务器准备好发送端应用程序所需的数据以后,以同样的方式将数据发送到发送端应用程序。

服务端

当浏览器的请求到达服务端之后,请求首先经过 Linux 虚拟服务器 LVS,调度器将网络请求分发到 Nginx 上。

  • 如果 Nginx 上缓存的有用户请求的内容,那么 Nginx 直接将用户请求的内容发送给浏览器。
  • 如果 Nginx 上没有缓存用户请求的内容,那么 Nginx 访问应用服务器(Web 服务器,比如 Java 的 Tomcat / Netty / Jetty,Python 的 Django)获取资源,再将用户请求的内容返回给浏览器。Nginx 会根据缓存策略缓存从应用服务器获取到的资源,浏览器也会根据缓存策略缓存收到的内容。

Nginx 也可以直接访问缓存系统尝试获取资源(Varnish 缓存静态资源,Redis 缓存动态资源)。如果缓存系统中没有用户请求的内容,再访问应用服务器获取资源。


当 Nginx 的请求到达应用服务器之后,请求首先经过 API 网关。API 网关根据路由规则,将外部访问网关地址的流量路由到内部服务集群中正确的服务节点上。网关还可以根据需要作为流量过滤器来使用,提供某些额外的可选的功能,例如:

  • 流量治理:流量控制、服务容错(限流、降级、熔断)
  • 安全防护、访问控制:防刷控制、防爬虫、黑白名单、认证、授权、数据完整性校验、数据加密
  • 监控:性能监控、日志监控
  • 其他:协议适配转换、缓存

外部访问网关地址的流量被路由到内部服务集群中正确的服务节点上之后,服务节点会再访问缓存系统(比如 Redis、EhCache 等),存储系统(比如 MySQL、PostgreSQL、MongoDB 等)实现业务操作,获取资源。

服务节点将获取到的资源返回给 API 网关,API 网关将资源返回给 Nginx,Nginx 再将用户请求的内容返回给客户端,客户端依据 HTTP 规则解析报文,并将用户请求的内容显示在页面上。

参考资料

08 | 键入网址再按下回车,后面究竟发生了什么? (geekbang.org)

域名 - 真正的飞鱼 - 博客园 (cnblogs.com)

URL编码 - 真正的飞鱼 - 博客园 (cnblogs.com)

计算机网络 | TCP 连接的建立 和 TCP 连接的断开 - 真正的飞鱼 - 博客园 (cnblogs.com)

《图解TCP / IP》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/388269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用Nginx给RStudio-Server配置https

前篇文档,我这边写了安装RStudio-Server的方法。默认是http的访问方式,现在我们需要将其改成https的访问方式。 1、给服务器安装Nginx:参照之前的安装Nginx的方法。 2、创建/usr/local/nginx/ssl目录: mkdir /usr/local/nginx/ss…

P6入门:了解P6 Professional 工具栏及地图分享

目录 引言 相关分享 引言 凭借更大的灵活性和增强的自定义功能,最新版本的 Oracle Primavera P6 Professional 的界面比早期版本有了巨大改进。对于有经验的伙伴来说,它仍然是熟悉的领域,几乎所有预期的功能都显示在前面。该界面可以更好地…

【汇编】三、寄存器(一只 Assember 的成长史)

嗨~你好呀! 我是一名初二学生,热爱计算机,码龄两年。最近开始学习汇编,希望通过 Blog 的形式记录下自己的学习过程,也和更多人分享。 上篇系列文章链接:【汇编】二、预备知识(一只 Assember 的…

Spring Boot结合IDEA自带Maven插件快速切换profile | Spring Cloud 10

一、前言 IDEA是目前 Java 开发者中使用最多的开发工具,它有着简约的设计风格,强大的集成工具,便利的快捷键。 在项目项目整个开发运维周期中,我们的的项目往往需要根据不同的环境,使用不同的文件配置。 比如以下部…

机器学习:Transformer

Transformer sequence-to-sequence(seq2seq) 很大语音没有文本,7000种中超半数没有文字。 遇到的问题: 遇到问题时候可以先不管它,先出一个baseline看看效果,后续再进行提升。 tts: 文本转语音,语音合成…

【图神经网络】李宏毅

GNN 引入 假如要预测一个人是否是凶手。可以通过每个角色的特征训练出一个分类器。 有没有我们忽略的信息,或者我们可以利用但没有完全利用的信息。就是角色的关系。 这些角色关系可以让我们在做分类的时候获得一些额外的信息,可以帮助我们做更好的mode…

C++ 断言

文章目录前言assertstatic_assert前言 断言(Assertion)是一种常用的编程手段,用于排除程序中不应该出现的逻辑错误。它是一种很好的Debug工具。其作用是判断表达式是否为真。C提供了assert和static_assert来进行断言。在C库中也有断言,其中断言与C的相同…

java @Autowired @Resource @Inject 三个注解的区别

javax.annotation.Resourcejdk 内置的,JSR-250 中的注解。依赖注入通过 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor 来处理。org.springframework.beans.factory.annotation.Autowired org.springframework.beans.factory.annotati…

汇编系列01-汇编语言简介

每天进步一点点,不要浮躁,沉下心来。 什么是汇编语言 我们知道CPU是经过精心设计的电路组成的,里面有很多微小的门电路,门电路是通过输入电平控制的,电平分为高低,我们用1表示高电平,0表示低电…

MySQL基础查询操作

文章目录🚏 Select语句🚀 一、SQL底层执行原理🚬 (一)、查询的结构🚬 (二)、SQL语句的执行过程🚭 1、WHERE 为什么不包含聚合函数的过滤条件?(面试…

Python | Leetcode刷题日寄Part05

欢迎交流学习~~ LeetCode & Python 系列: 🏆 Python | Leetcode刷题日寄Part01 🔎 Python | Leetcode刷题日寄Part02 💝 Python | Leetcode刷题日寄Part03 ✈️ Python | Leetcode刷题日寄Part04 Python|Leetcode刷题日寄Par…

【企业服务器LNMP环境搭建】nginx安装

1、介绍(官方网址:nginx news ) 1.1 常见用法 1) web服务器软件 httpd http协议 同类的web服务器软件:apache nginx(俄罗斯) IIS(微软 fastcgi) lighttpd(德国) 2)代理服务器 反向代理 3)邮箱代理服务器 IMAP POP3 SMTP 4)负载均…

前端ES6异步编程技术——Promise使用

Promise是什么 官方的定义是:Promise是ES6新推出的用于进行异步编程的解决方案,旧方案是单纯使用回调函数来解决的。对于开发人员来说,我们把promise当作一个普通的对象即可,使用它可以用来封装一个异步操作并可以获取其成功/失败…

Spring Cloud(微服务)学习篇(六)

Spring Cloud(微服务)学习篇(六) 2 Sentinel实现流量规则(控制台版) 2.1 变更pom.xml(shop-user-server项目)代码 2.1.1 加入如下依赖 <!--熔断限流--> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-…

稀疏子空间聚类——对超像素聚类

如何使用&#xff1a;超像素分割算法进行过分割——>对所有的超像素样本提取新特征(包括对比度增强直方图特征、超像素样本邻域纹理特征、基于先验知识的位置信息特征)——>采用距离约束优化的稀疏子空间聚类算法(对超像素样本进行聚类) 在超像素分割中构造自适应相似度系…

【linux】:进程状态(僵尸进程等)以及环境变量

文章目录 前言一.进程状态 进程的优先级二.环境变量总结前言 本篇文章是接着上一篇【linux】:进程概念的后续&#xff0c;对于有基础的同学可以直接看这篇文章&#xff0c;对于初学者来说强烈建议大家从上一篇的概念开始看起&#xff0c;上一篇主要解释了冯诺依曼体系以及操…

将 Visual Studio Code 设置为3dmax Maxscript脚本编辑器的方法详解

Visual Studio Code对Autodesk 3dMax脚本语言 (MaxScript) 支持 本教程给大家分享Visual Studio Code对Autodesk 3dMax 脚本语言 (MaxScript) 支持。 MXSPyCOM项目&#xff1a;允许从外部代码编辑器编辑和执行3dMax MaxScript和Python文件。 功能特性 语法高亮。语法错误检查语…

x86 平台利用 qemu-user-static 实现 arm64 平台 docker 镜像的运行和构建

文章目录[toc]关于 docker 版本查看是否开启 experimental 功能开启 experimental 功能查看当前环境平台拉取一个 arm 平台的容器运行一个 arm 平台的容器整一个 qemu-user-static注册可支持的架构解释器尝试启动 arm64 镜像尝试启动 ppc64le 镜像后台运行 arm64 容器build 一个…

Libgdx 导入blender 3D动画

导入blender3D模型可以看上篇libgdx导入blender模型 本篇3D动画在上篇的基础上。 具体参考官网 3D 动画和蒙皮 blender动画参考 八个案例教程带你从0到1入门blender【已完结】 打开上次的blender的&#xff0c;选则物体属性 点击位置和旋转x&#xff0c;y&#xff0c;z后面…

一个好的工程项目管理软件所包含的主要功能

工程项目管理软件哪个好&#xff1f;借助Zoho Projects强大的工程项目管理软件&#xff0c;您的团队可以在预算范围内按时交付。从质量保证到预算规划&#xff0c;Zoho Projects的工程项目管理平台旨在推动切实的成果是Zoho Projects工程项目管理软件的优势。 高质量的可交付成…