关于java:在浏览器输入-URL-回车后会发生什么

41次阅读

共计 5326 个字符,预计需要花费 14 分钟才能阅读完成。

作者:4Ark
起源:https://4ark.me/post/b6c7c0a2…

这个问题曾经是陈词滥调了,更是常常被作为面试的压轴题呈现,网上也有很多文章,但最近闲的无聊,而后就本人做了一篇笔记,感觉比之前了解更透彻了。

留神:本文的步骤是建设在,申请的是一个简略的 HTTP 申请,没有 HTTPS、HTTP2、最简略的 DNS、没有代理、并且服务器没有任何问题的根底上,只管这是不切实际的。

大抵流程

  • URL 解析
  • DNS 查问
  • TCP 连贯
  • 解决申请
  • 承受响应
  • 渲染页面

一、URL 解析

地址解析:

首先判断你输出的是一个非法的 URL 还是一个待搜寻的关键词,并且依据你输出的内容进行主动实现、字符编码等操作。

HSTS

因为安全隐患,会应用 HSTS 强制客户端应用 HTTPS 拜访页面

其余操作

浏览器还会进行一些额定的操作,比方安全检查、拜访限度(之前国产浏览器限度 996.icu)。

查看缓存

二、DNS 查问

根本步骤

1. 浏览器缓存

浏览器会先查看是否在缓存中,没有则调用零碎库函数进行查问。

2. 操作系统缓存

操作系统也有本人的 DNS 缓存,但在这之前,会向查看域名是否存在本地的 Hosts 文件里,没有则向 DNS 服务器发送查问申请。

3. 路由器缓存

路由器也有本人的缓存。

4. ISP DNS 缓存

ISP DNS 就是在客户端电脑上设置的首选 DNS 服务器,它们在大多数状况下都会有缓存。

根域名服务器查问

在后面所有步骤没有缓存的状况下,本地 DNS 服务器会将申请转发到互联网上的根域,上面这个图很好的诠释了整个流程:

根域名服务器(维基百科)

须要留神的点

递归形式:一路查上来两头不返回,失去最终后果才返回信息(浏览器到本地 DNS 服务器的过程)

迭代形式,就是本地 DNS 服务器到根域名服务器查问的形式。

什么是 DNS 劫持

前端 dns-prefetch 优化

三、TCP 连贯

TCP/IP 分为四层,在发送数据时,每层都要对数据进行封装:

1. 应用层:发送 HTTP 申请

在后面的步骤咱们曾经失去服务器的 IP 地址,浏览器会开始结构一个 HTTP 报文,其中包含:

  • 申请报头(Request Header):申请办法、指标地址、遵循的协定等等
  • 申请主体(其余参数)

其中须要留神的点:浏览器只能发送 GET、POST 办法,而关上网页应用的是 GET 办法

2. 传输层:TCP 传输报文

传输层会发动一条达到服务器的 TCP 连贯,为了不便传输,会对数据进行宰割(以报文段为单位),并标记编号,不便服务器承受时可能精确地还原报文信息。

在建设连贯前,会先进行 TCP 三次握手。

对于 TCP/IP 三次握手,网上曾经有很多段子和图片活泼地形容了,大家能够看下这篇:为什么 TCP 建设连贯是三次握手,敞开连贯确是四次挥手呢?

3. 网络层:IP 协定查问 Mac 地址

将数据段打包,并退出源及指标的 IP 地址,并且负责寻找传输路线。

判断指标地址是否与以后地址处于同一网络中,是的话间接依据 Mac 地址发送,否则应用路由表查找下一跳地址,以及应用 ARP 协定查问它的 Mac 地址。

  留神:在 OSI 参考模型中 ARP 协定位于链路层,但在 TCP/IP 中,它位于网络层。

4. 链路层:以太网协定

以太网协定

依据以太网协定将数据分为以“帧”为单位的数据包,每一帧分为两个局部:

  • 标头:数据包的发送者、接受者、数据类型
  • 数据:数据包具体内容

Mac 地址

以太网规定了连入网络的所有设施都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是举世无双的,具备了一对一的能力。

播送

发送数据的办法很原始,间接把数据通过 ARP 协定,向本网络的所有机器发送,接管方依据标头信息与本身 Mac 地址比拟,统一就承受,否则抛弃。

留神:接管方回应是单播。

服务器承受申请

承受过程就是把以上步骤逆转过去,参见上图。

四、服务器解决申请

大抵流程

HTTPD

最常见的 HTTPD 有 Linux 上罕用的 Apache 和 Nginx,以及 Windows 上的 IIS。

它会监听失去的申请,而后开启一个子过程去解决这个申请。

解决申请

承受 TCP 报文后,会对连贯进行解决,对 HTTP 协定进行解析(申请办法、域名、门路等),并且进行一些验证:

  • 验证是否配置虚拟主机
  • 验证虚拟主机是否承受此办法
  • 验证该用户能够应用该办法(依据 IP 地址、身份信息等)

重定向

如果服务器配置了 HTTP 重定向,就会返回一个 301永恒重定向响应,浏览器就会依据响应,从新发送 HTTP 申请(从新执行下面的过程)。

URL 重写

而后会查看 URL 重写规定,如果申请的文件是实在存在的,比方图片、html、css、js 文件等,则会间接把这个文件返回。否则服务器会依照规定把申请重写到 一个 REST 格调的 URL 上。而后依据动静语言的脚本,来决定调用什么类型的动静文件解释器来解决这个申请。

以 PHP 语言的 MVC 框架举例,它首先会初始化一些环境的参数,依据 URL 由上到下地去匹配路由,而后让路由所定义的办法去解决申请。

关注微信公众号:Java 技术栈,在后盾回复:架构,能够获取我整顿的 N 篇最新架构教程,都是干货。

五、浏览器承受响应

浏览器接管到来自服务器的响应资源后,会对资源进行剖析。

首先查看 Response header,依据不同状态码做不同的事(比方下面提到的重定向)。

如果响应资源进行了压缩(比方 gzip),还须要进行解压。

而后,对响应资源做缓存。

接下来,依据响应资源里的 MIME[3] 类型去解析响应内容(比方 HTML、Image 各有不同的解析形式)。

六、渲染页面

浏览器内核

不同的浏览器内核,渲染过程也不完全相同,但大抵流程都差不多。

根本流程

6.1. HTML 解析

首先要晓得浏览器解析是从上往下一行一行地解析的。

解析的过程能够分为四个步骤:

① 解码(encoding)

传输回来的其实都是一些二进制字节数据,浏览器须要依据文件指定编码(例如 UTF-8)转换成字符串,也就是 HTML 代码。

② 预解析(pre-parsing)

预解析做的事件是提前加载资源,缩小解决工夫,它会辨认一些会申请资源的属性,比方 img 标签的 src 属性,并将这个申请加到申请队列中。

③ 符号化(Tokenization)

符号化是词法剖析的过程,将输出解析成符号,HTML 符号包含,开始标签、完结标签、属性名和属性值。

它通过一个状态机去辨认符号的状态,比方遇到 <> 状态都会产生变动。

④ 构建树(tree construction)

留神:符号化和构建树是并行操作的,也就是说只有解析到一个开始标签,就会创立一个 DOM 节点。

在上一步符号化中,解析器取得这些标记,而后以适合的办法创立 DOM 对象并把这些符号插入到 DOM 对象中。

<html><head><title>Web page parsing</title></head><body><div><h1>Web page parsing</h1><p>This is an example Web page.</p></div></body></html>

浏览器容错进制

你素来没有在浏览器看过相似”语法有效”的谬误,这是因为浏览器去纠正错误的语法,而后持续工作。

事件

当整个解析的过程实现当前,浏览器会通过 DOMContentLoaded 事件来告诉 DOM 解析实现。

6.2. CSS 解析

一旦浏览器下载了 CSS,CSS 解析器就会解决它遇到的任何 CSS,依据语法标准 [4] 解析出所有的 CSS 并进行标记化,而后咱们失去一个规定表。

CSS 匹配规定

在匹配一个节点对应的 CSS 规定时,是依照从右到左的程序的,例如:div p {font-size :14px}会先寻找所有的 p 标签而后判断它的父元素是否为div

所以咱们写 CSS 时,尽量用 id 和 class,千万不要适度层叠。

6.3. 渲染树

其实这就是一个 DOM 树和 CSS 规定树合并的过程。

留神:渲染树会疏忽那些不须要渲染的节点,比方设置了 display:none 的节点。

计算

通过计算让任何尺寸值都缩小到三个可能之一:auto、百分比、px,比方把 rem 转化为px

级联

浏览器须要一种办法来确定哪些款式才真正须要利用到对应元素,所以它应用一个叫做 specificity 的公式,这个公式会通过:

  • 标签名、class、id
  • 是否内联款式
  • !important

而后得出一个权重值,取最高的那个。

渲染阻塞

当遇到一个 script 标签时,DOM 构建会被暂停,直至脚本实现执行,而后持续构建 DOM 树。

但如果 JS 依赖 CSS 款式,而它还没有被下载和构建时,浏览器就会提早脚本执行,直至 CSS Rules 被构建。

所有咱们晓得:

  • CSS 会阻塞 JS 执行
  • JS 会阻塞前面的 DOM 解析

为了防止这种状况,应该以下准则:

  • CSS 资源排在 JavaScript 资源后面
  • JS 放在 HTML 最底部,也就是 </body>

另外,如果要扭转阻塞模式,能够应用 defer 与 async。

6.4. 布局与绘制

确定渲染树种所有节点的几何属性,比方:地位、大小等等,最初输出一个盒子模型,它能精准地捕捉到每个元素在屏幕内的精确地位与大小。

而后遍历渲染树,调用渲染器的 paint() 办法在屏幕上显示其内容。

6.5. 合并渲染层

把以上绘制的所有图片合并,最终输入一张图片。

6.6. 回流与重绘

回流(reflow)

当浏览器发现某个局部发现变动影响了布局时,须要倒回去从新渲染,会从 html 标签开始递归往下,从新计算地位和大小。

reflow 根本是无奈防止的,因为当你滑动一下鼠标、resize 窗口,页面就会产生变动。

重绘(repaint)

扭转了某个元素的背景色、文字色彩等等不会影响四周元素的地位变动时,就会产生重绘。

每次重绘后,浏览器还须要合并渲染层并输入到屏幕上。

回流的老本要比重绘高很多,所以咱们应该尽量避免产生回流。

比方:display:none 会触发回流,而 visibility:hidden 只会触发重绘。

6.7. JavaScript 编译执行

大抵流程

能够分为三个阶段:

1. 词法剖析

JS 脚本加载结束后,会首先进入语法分析阶段,它首先会剖析代码块的语法是否正确,不正确则抛出“语法错误”,进行执行。

几个步骤:

  • 分词,例如将 var a = 2,,分成vara=2 这样的词法单元。
  • 解析,将词法单元转换成形象语法树(AST)。
  • 代码生成,将形象语法树转换成机器指令。

2. 预编译

JS 有三种运行环境:

  • 全局环境
  • 函数环境
  • eval

每进入一个不同的运行环境都会创立一个对应的执行上下文,依据不同的上下文环境,造成一个函数调用栈,栈底永远是全局执行上下文,栈顶则永远是以后执行上下文。

创立执行上下文

创立执行上下文的过程中,次要做了以下三件事:

  • 创立变量对象
  • 参数、函数、变量
  • 建设作用域链
  • 确认以后执行环境是否能拜访变量
  • 确定 This 指向

3. 执行

JS 线程

尽管 JS 是单线程的,但实际上参加工作的线程一共有四个:

其中三个只是帮助,只有 JS 引擎线程是真正执行的

其中三个只是帮助,只有 JS 引擎线程是真正执行的

JS 引擎线程:也叫 JS 内核,负责解析执行 JS 脚本程序的主线程,例如 V8 引擎事件触发线程:属于浏览器内核线程,次要用于管制事件,例如鼠标、键盘等,当事件被触发时,就会把事件的处理函数推动事件队列,期待 JS 引擎线程执行定时器触发线程:次要管制 setIntervalsetTimeout,用来计时,计时结束后,则把定时器的处理函数推动事件队列中,期待 JS 引擎线程。HTTP 异步申请线程:通过 XMLHttpRequest 连贯后,通过浏览器新开的一个线程,监控 readyState 状态变更时,如果设置了该状态的回调函数,则将该状态的处理函数推动事件队列中,期待 JS 引擎线程执行。

注:浏览器对同一域名的并发连接数是无限的,通常为 6 个。

宏工作

分为:

  • 同步工作:依照程序执行,只有前一个工作实现后,能力执行后一个工作
  • 异步工作:不间接执行,只有满足触发条件时,相干的线程将该异步工作推动工作队列中,期待 JS 引擎主线程上的工作执行结束时才开始执行,例如异步 Ajax、DOM 事件,setTimeout 等。

微工作

微工作是 ES6 和 Node 环境下的,次要 API 有:Promiseprocess.nextTick

微工作的执行在宏工作的同步工作之后,在异步工作之前。

代码例子

console.log('1'); // 宏工作 同步
setTimeout(function() {console.log('2');     // 宏工作 异步})
new Promise(function(resolve) {console.log('3');     // 宏工作 同步    
    resolve();}).then(function() {console.log('4')// 微工作})
    console.log('5') // 宏工作 同步

以上代码输入程序为:1,3,5,4,2

近期热文举荐:

1.Java 15 正式公布,14 个新个性,刷新你的认知!!

2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3. 我用 Java 8 写了一段逻辑,共事直呼看不懂,你试试看。。

4. 吊打 Tomcat,Undertow 性能很炸!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0