从输入URL到页面加载完成的过程中都发生了什么事情?

从输入URL到页面加载完成的过程中都发生了什么事情?

一、初始准备(服务器端)

1.服务器启动监听服务,准备迎接来自客户机的请求。服务器启动操作系统—启动http服务进程(apache or nginx or ..)--服务进程开始定位到服务器上的www文件夹,一般是位于/var/www。

2.服务器启动一些附属的模块。例如php,或者,使用fastcgi方式连接到php的fpm管理进程。

3.向操作系统申请一个tcp连接

4.绑定在80端口

5.调用了accept函数

6.开始监听。监听着可能来自位于地球任何一个地方的请求,随时准备做出响应

补充:典型的情况下,机房里面应该还有一个数据库服务器,或许,还有一台缓存服务器,如果对于流量巨大的网站,那么动态脚本的解释器可能还有单独的物理机器来跑,如果是中小的站点,那么,上述的各色服务,甚至都可能在一台物理机上,不管怎么说,他们做好了准备,静候差遣。

二、查找服务器IP

1.输入地址URL(Uniform Resource Identifier统一资源标识符)。键盘上的每个按键都有不同的电频,通过按键,电脑得知输入的内容。在浏览器中输入网址的时候,浏览器其实就已经在智能的匹配可能得url了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的url,然后给出智能提示。

2.把URL分割成几个部分:协议、网络地址、资源路径。例如:http://www.guokr.com/question/554991/中<协议:http>从该计算机获取资源的方式,常见的是HTTP、HTTPS、FTP、FILE,不同协议有不同的通讯内容格式;<网络地址: www.guokr.com>指示该连接网络上哪一台计算机,可以是域名或者IP地址,可以包括端口号。通常端口号不常见是因为大部分的都是使用默认端口,如HTTP默认端口80,HTTPS默认端口443。更多详细内容请参考:同源策略和跨域问题;<资源路径: /question/554991/>指示从服务器上获取哪一项资源。我们最常见的的协议是HTTP协议,除此之外还有加密的HTTPS协议、FTP协议、FILe协议等等。

3.DNS解析域名(根据域名找ip)

根据浏览器缓存->操作系统缓存(host)->路由器缓存->DNS服务器…..->全世界的顶级DNS上,逐级递归向上找,找到该域名对应的IP地址。DNS同时占用UDP和TCP的53端口。客户端进行DNS查询时,一般使用UDP协议,而域名服务器之间进行区域传输,例如数据同步时则使用TCP协议。(此处可根据传输数据量来理解,其中UDP报文的最大长度为512字节,而TCP则允许报文长度超过512字节。)

浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;

操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统,获取操作系统的记录(保存最近的DNS查询缓存);

路由器缓存如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;

ISP缓存:若上述均失败,继续向ISP搜索。ISP(Internet Service Provider),互联网服务提供商,即电信运营商。

补充:

A.IP地址对应着网络上一台计算机,DNS服务器本身也有IP,你的网络设置包含DNS服务器的IP。

B.如果有病毒把一些常用的域名,修改hosts文件,指向一些恶意的IP,那么浏览器也会不加判断的去连接。

C.在不同的地区或者不同的网络(电信、联通、移动)的情况下,转换后的IP地址很可能是不一样的,这首先涉及到负载均衡的第一步。即,通过DNS解析域名时将你的访问分配到不同的入口,同时尽可能保证你所访问的入口是所有入口中可能较快的一个。

三、客户端和服务器进行连接

1.向确定的IP和端口号,构造一个http请求

确定端口号。端口号之于计算机就像窗口号之于银行,一家银行有多个窗口,每个窗口都有个号码,不同窗口可以负责不同的服务。端口只是一个逻辑概念,和计算机硬件没有关系。例如:www.guokr.com不包含端口号,http协议默认端口号是80。如果你输入的url是http://www.guokr.com:8080/,那表示不使用默认的端口号,而使用指定的端口号8080。

发起请求方法。一个典型的http request header一般需要包括请求的方法,例如GET或者POST等,不常用的还有PUT和DELETE方法,更加不常用的还有HEAD和OPTION以及TRACE方法,一般的浏览器只能发起GET或者POST请求,

2.浏览器发起一条tcp连接(传输层)

开始三次握手的过程,tcp包被封装到网络层的ip包里面,ip包再被封装到数据链路层的数据帧结构中,再通过物理层的比特流送出去。这些分层的意义在于分工合作,数据链路层通过CSMA/CD协议保证了相邻两台主机之间的数据报文传递,而网络层的ip数据包通过不同子网之间的路由器的路由算法和路由转发,保证了互联网上两台遥远主机之间的点对点的通讯,不过这种传输是不可靠,于是可靠性就由传输层的tcp协议来保证。tcp通过慢开始,乘法减小等手段来进行流量控制和拥塞避免,同时提供了两台遥远主机上进程到进程的通信,最终保证了http的请求头能够被远方的服务器上正在监听的http服务器进程收到。终于,数据包在跳与跳之间被拆了又封装,在子网与子网之间被转发了又转发,最后进入了服务器的操作系统的缓冲区。服务器的操作系统由此给正在被阻塞住的accept函数一个返回,将他唤醒。

3.握手成功后,浏览器向服务器发送http请求,请求数据包。

如果资源路径指示的资源不存在,服务器就会返回著名的404错误。

4.服务器接受并处理HTTP报文

请求进入服务器之后,服务器上的的http监听进程会得到这个请求,然后一般情况下会启动一个新的子进程去处理这个请求,同时父进程继续监听。

http服务器首先会查看重写规则,然后如果是文件真实存在,例如一些图片,或者css js等的静态文件,就会直接把这个文件返回,如果是一个动态的请求,那么会根据url重写模块的规则,把这个请求重写到一个rest风格的url上,然后根据动态语言的脚本,来决定调用什么类型的动态文件脚本解释器来处理这个请求。

5.服务器构造并发送响应报文(传输过程略

在视图层把页面准备好后,再从动态脚本解释器送回到http服务器,由http服务器把这些正文加上一个响应头,封装成一个标准的http响应包,再通过TCP/IP协议,送回到客户机浏览器。

前端开发人员会将并发加载的资源文件分布在好多个域名下,变相的绕过浏览器的限制。即,浏览器在同一个域名下并发加载的资源数量是有限制的,例如ie6-7是两个,ie8是6个,chrome各版本不大一样,一般是4-6个。

四、渲染

当浏览器接收到报文,根据收到的资源的类型,将资源组织成屏幕上显示的图像,这个过程叫渲染。网页渲染是浏览器最复杂、最核心的功能。

1.浏览器判断状态码。

当请求的响应到达客户端的浏览器后,响应到达浏览器之后,浏览器首先判断状态码。

1xx:指示信息–表示请求已接收,继续处理。

2xx:成功–表示请求已被成功接收、理解、接受,直接进入渲染流程。。

3xx:重定向–要完成请求必须进行更进一步的操作。即要去相应头里面找location域,根据这个location的指引,进行跳转,这里跳转需要开启一个跳转计数器,是为了避免两个或者多个页面之间形成的循环的跳转,当跳转次数过多之后,浏览器会报错,同时停止。

4xx:客户端错误–请求有语法错误或请求无法实现。

5xx:服务器端错误–服务器未能实现合法的请求。

2.当得到一个正确的200响应之后,进行语言的编码解析。

响应头是一个ascii的标准字符集的文本,这个还好办,但是响应的正文本质上就是一个字节流,对于这一坨字节流,浏览器要怎么去处理呢,首先浏览器会去看响应头里面指定的encoding域,如果有了这个东西,那么就按照指定的encoding去解析字符,如果没有的话,那么浏览器会使用一些比较智能的方式,去猜测和判断这一坨字节流应该使用什么字符集去解码。相关的笔记可以看这里,浏览器对编码的确定

3.解析html构建dom树

此时DOM树只是一个树形结构,没规定每个DOM节点的样式。在html语言嵌套正常而且规范的情况下,这种xml标记的语言是比较容易的能够构建出一棵dom树出来的,当然,对于互联网上大量的不规范的页面,不同的浏览器应该有自己不同的容错去处理。构建出来的dom本质上还是一棵抽象的逻辑树,

构建dom树的过程中,如果遇到了由script标签包起来的js动态脚本代码,那么会把代码送到js引擎里面去跑,如果遇到了style标签包围起来的css代码,也会保存下来,用于稍后的渲染。如果遇到了img等引用外部文件的标签,那么浏览器会根据指定的url再次发起一个新的http请求,去把这个文件拉取回来,值得一提的是,对于同一个域名下的下载过程来说,浏览器一般允许的并发请求是有限的,通常控制在两个左右,所以如果有很多的图片的话,一般出于优化的目的,都会把这些图片使用一台静态文件的服务器来保存起来,负责响应,从而减少主服务器的压力。

4.根据CSS生成CSSOM

5.构造render树

将DOM和CSSOM整合形成RenderTree(渲染树)。结构和DOM树一样,是树形结构,但每个节点中的样式(位置、长、宽、高、颜色、背景图片布局等)被标识出来。render树一旦构建完成,整个页面也就准备好了。

6.布局render树

7.绘制render树。注意,当遇到

你可能感兴趣的:(从输入URL到页面加载完成的过程中都发生了什么事情?)