输入一个URL后的详细过程

目录

1.DNS解析

2. TCP连接

3.浏览器发送HTTP请求

4.服务器处理请求

5、释放连接 TCP 连接

6、客户端浏览器解析 HTML 内容

6.浏览器解析渲染页面

8.DNS的递归查询和迭代查询

 一、主机向本地域名服务器的查询一般都是采用递归查询。

二、本地域名服务器向根域名服务器的查询的迭代查询。


1.DNS解析

输入一个网址并按回车之后浏览器会根据输入的URL查找对应的IP,具体过程如下:
(1)查找浏览器缓存,浏览器会保存一段时间内访问过的一些网址的DNS信息。
(2)如果没有找到对应的IP,浏览器就调用操作系统缓存来继续查找这个网址的DNS信息。
(3)如果还是没找到对应的IP,就发送一个请求到路由器上,路由器在路由器缓存上查找记录的DNS信息。
(4)如果还是没有找到对应的IP,这个请求就会被发送到本地DNS服务器,本地DNS上缓存了一张域名与之IP地址对应的表格,有就直接返回域名对应的IP地址
(5)如果还是没有找到对应的IP, ISP的DNS服务器(本地DNS服务器)会将请求发向根域名服务器,然后到顶级域名DNS再到权威DNS,权威DNS是域名解析结果的原出处,它查询到对应的IP地址后告诉本地DNS。
(6)如果到了这里还是找不到域名的对应信息,那就域名错误了。找到的话,本地DNS服务器就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。

         DNS根据域名查询IP地址的过程为:浏览器缓存 --> 操作系统缓存 --> 路由器缓存–>本地DNS缓存 --> 根DNS–>顶级DNS–>权威DNS。DNS

2. TCP连接

浏览器得到IP后,向服务器发送TCP连接。TCP三次握手目前HTTP协议大多都是1.1,在1.1的协议里,默认开启了keep-alive,这样建立的TCP连接,可以在多次请求中复用,不需要重新连接。

拿到域名对应的IP地址之后,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序(常用的有httpd,nginx等)80端口发起TCP的连接请求这个连接请求到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接。

3.浏览器发送HTTP请求

浏览器和服务器建立连接以后,浏览器就给这个IP地址的服务器发送一个http请求,就是去服务器获取一些资源,对于访问页面来说,要获取的页资源往往是一个页面。

其本质是在建立起的TCP连接中,按照HTTP协议标准发送一个索要网页的请求。通过 TCP 套接字,客户端向 Web 服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据 4 部分组成。

发送完请求接下来就是等待回应了。

4.服务器处理请求

服务器收到浏览器的请求以后,会解析这个请求(读请求头),然后生成一个响应头和具体响应内容。接着服务器会传回来一个响应头和一个响应,响应头告诉了浏览器一些必要的信息,例如重要的Status Code,2开头如200表示一切正常,3开头表示重定向,4开头是客户端错误,如404表示请求的资源不存在,5开头表示服务器端错误。响应就是浏览器请求的页面内容。

Web 服务器解析请求,定位请求资源。服务器将资源复本写到 TCP 套接字,由客户端 读取。一个响应由状态行、响应头部、空行和响应数据 4 部分组成。

5、释放连接 TCP 连接

若 connection 模式为 close,则服务器主动关闭 TCP 连接,客户端被动关闭连接, 释放 TCP 连接;connection 模式为 keepalive,则该连接会保持一段时间,在该时间内 可以继续接收请求;

6、客户端浏览器解析 HTML 内容

客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响 应头,响应头告知以下为若干字节的 HTML 文档和文档的字符集。客户端浏览器读取响应数据 HTML,根据 HTML 的语法对其进行格式化,并在浏览器窗口中显示。

 

6.浏览器解析渲染页面

在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了,浏览器是如何把页面呈现在屏幕上的呢?不同浏览器可能解析的过程不太一样,这里我们只介绍webkit的渲染过程,下图对应的就是WebKit渲染的过程,这个过程包括:

解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树。

浏览器在解析html文件时,会”自上而下“加载,并在加载过程中进行解析渲染。在解析过程中,如果遇到请求外部资源时,如图片、外链的CSS、iconfont等,请求过程是异步的,并不会影响html文档进行加载。

  解析过程中,浏览器首先会解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)。

  DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。

  页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。

 当文档加载过程中遇到js文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程。因为JS有可能会修改DOM,最为经典的document.write,这意味着,在JS执行完成前,后续所有资源的下载可能是没有必要的,这是js阻塞后续资源下载的根本原因。所以我明平时的代码中,js是放在html文档末尾的。

  JS的解析是由浏览器中的JS解析引擎完成的,比如谷歌的是V8。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如IO读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。

  JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)。具体的过程可以看我这篇文章:点击这里

7.什么是DNS?

  DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。

  通俗的讲,我们更习惯于记住一个网站的名字,比如www.baidu.com,而不是记住它的ip地址,比如:167.23.10.2。而计算机更擅长记住网站的ip地址,而不是像www.baidu.com等链接。因为,DNS就相当于一个电话本,比如你要找www.baidu.com这个域名,那我翻一翻我的电话本,我就知道,哦,它的电话(ip)是167.23.10.2。

8.DNS的递归查询和迭代查询

 一、主机向本地域名服务器的查询一般都是采用递归查询。

        所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户的身份,

        向其它根域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。

        因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询到所需的IP地址。

二、本地域名服务器向根域名服务器的查询的迭代查询。

       迭代查询的特点:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地服务器:“你下一步应当向哪一个域名服务器进行查询”。

        然后让本地服务器进行后续的查询。根域名服务器通常是把自己知道的顶级域名服务器的IP地址告诉本地域名服务器,让本地域名服务器再向顶级域名服务器查询。

        顶级域名服务器在收到本地域名服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地服务器下一步应当向哪一个权限域名服务器进行查询。

        最后,知道了所要解析的IP地址或报错,然后把这个结果返回给发起查询的主机