zoukankan      html  css  js  c++  java
  • 从输入url到页面加载发生了什么?

    过程:

    1、 域名解析(获得IP地址)

    2、 发起TCP连接

    3、建立TCP连接后发起HTTP请求

    4、服务器端处理HTTP请求,浏览器接收HTTP响应。

    5、浏览器解析渲染页面

     

    一、域名解析

    DNS解析的过程就是寻找哪台机器上有你需要的资源的过程,互联网上每一台计算机的唯一标识就是它的IP地址,所以域名解析会将一个网址转换为IP地址。

     

    解析过程:

    上图是查找www.google.com的IP地址的过程。

    首先在本地域名服务器中查找ip地址,如果没有找到,本地域名服务器会向根域名服务器发送一个请求。

    如果根域名服务器也没有,则根域名服务器会向com顶级服务器发送请求,以此类推下去。

    直到最后本地域名服务器获得ip地址并把它缓存到本地,供下次查询使用。

     从上述过程中,可以看出解析过程是从右向左的:. ->com->google.com->www.google.com

    具体过程:

    (1)在浏览器缓存中查找该域名对应的IP地址;

    (2)在本机系统查找是否缓存过IP,(系统自己也具备域名解析的能力);

    (3)向本地域名服务器发送请求

      本地域名系统一般是本地区的域名服务器,比如连接的校园网,那么域名解析系统就在校园的机房里;如果连接的是电信、移动等网络,那么本地域名解析系统就在北地区,有各自的运营商来提供服务。

    (4)向根域名服务器发送请求。

    。。。。。

    查询的两种方式:

    (1)递归查询。 

    如果主机所询问的本地域名服务器不知道被查询的域名的ip地址,那么本地域名服务器就以DNS客户的身份,向其他根域名服务器继续发出查询请求报文,而不是让主机自己进行下一步查询。

    (2)迭代查询 (每次都需要本地域名服务器去查找)

    当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的ip地址,要么告诉本地服务器下一步应该向哪一个域名服务器进行查询,然后让本地域名服务器进行后续查询。

     

    DNS负载均衡

    当用户访问量巨大时,同时访问主机会使主机崩掉,因此使用负载均衡来解决这个问题。

    原理:在DNS服务器中为同一主机分配多个IP地址(也就是多个服务器),当进行DNS解析时,通过算法根据主机的负载情况,返回IP地址。

     

    DNS缓存

    DNS存在着多级缓存,按照离浏览器的距离排序的话,有:浏览器缓存、系统缓存、路由器缓存、IPS服务器缓存、根域名服务器缓存、顶级域名服务器缓存、主域名服务器缓存。

    优化:减少DNS解析的时间。

     

    二、TCP连接

    HTTP协议是使用TCP作为其传输层协议的。

     

    TCP首部:默认长度为20B,包括源端口、目的端口、序号、确认号等。

     

    第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

    第二次握手服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

    第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

     第一步:客户端向服务器发出连接请求的报文段,其首部中的同步位SYN=1(SYN报文不能携带数据,但是要消耗一个序号),并选择序列号seq=x,表明传送数据时的第一个数据字节的序号是x。

    第二步:服务器收到数据报,并从SYN=1知道这是一个建立连接的请求,如果同意,则发回确认;服务器在确认报文中应使用SYN=1,ACK=1,其确认号ack=x+1,自己的序列号为seq=y。

    第三步:客户端收到报文段后向服务器给出确认,其ACK=1,确认ack=y+1。 

    为什么连接的时候是三次握手,关闭的时候却是四次握手?
    答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

    TCP连接为什么不能是两次或者四次?

      假设没有第三次握手,服务器在客户端的请求进行响应(第二次握手)后,就会理所当然的认为已经建立连接了,但是在返回相应过程中可能会丢包,如果客户端并没有收到服务端的确认包的话,会认为连接未建立,然而服务端会对已建立的连接保存必要的资源。所以不能是两次。

      完全可靠的通信协议是根本不存在的,而三次握手之后,客户端和服务端至少可以确认之前的通信情况,但是无法确认之后的情况。所以无论是四次还是五次dou'shi  徒劳的,所以三次是最佳的次数。

    三、发送HTTP请求

    HTTP请求报文是由三部分组成:请求行、请求头和请求正文

    请求行:

    格式:Method Request-URL HTTP-Version CRLF

    例:GET index.html HTTP/1.1

    请求行包括请求方法、url字段以及http协议版本

    常用Method方法有:GET、POST、PUT、DELETE

    请求头:

    作用:允许客户端向服务器传递请求的附加信息和客户端的信息

    常见的请求头有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等。

    请求正文:

    当使用POST或PUT方式时,表示客户端需要向服务器端传输数据,传输的数据放在请求正文中,同时请求头中也会包含一些与请求正文相关的数据。

    如:当请求的数据采用json的数据格式时,需要设置请求头的Content-Type:Application/json。

    优化:

    减少HTTP请求次数:如合并文件、雪碧图等。

    四、服务器处理请求并返回HTTP响应

    HTTP响应报文由三部分组成:状态码、响应头和响应报文。

    状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:

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

      • 2xx:成功–表示请求已被成功接收、理解、接受。

      • 3xx:重定向–要完成请求必须进行更进一步的操作。

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

      • 5xx:服务器端错误–服务器未能实现合法的请求。
        平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分别表示什么请自行查找)。

    响应头:主要由Cache-Control、 Connection、Date、Pragma、server等组成。

    响应报文:服务器返回给浏览器的文本信息。主要有html、css、js、图片等组成

    五、浏览器解析渲染页面

    浏览器渲染机制:

    (1)浏览器的HTML解析器会将HTML文件解析成一棵DOM树,DOM树的构建是一个深度遍历的过程,当前节点的所有子节点都构建完成后,才会去构建当前节点的下一个兄弟节点。

    (2)解析CSS文件构建CSSOM树

    (3)根据DOM树(存储节点信息)和CSSOM树(存储节点渲染信息)构建渲染树,一些像head或display:none这些没必要放在渲染树中了。这棵树中包含了页面所有可见元素及其渲染信息。

    (4)布局:渲染树生成后,浏览器根据渲染树中的信息,结合设备的屏幕信息,计算每个元素的位置和尺寸。

    (5)渲染:得到了渲染树及其节点的布局信息,浏览器便可以将最终的页面渲染到屏幕上。

    这个过程涉及两个概念:reflow(回流)和repain(重绘)

    Reflow,也称作Layout,中文叫回流,一般意味着元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树,这个过程称为Reflow。

    Repaint,中文重绘,意味着元素发生的改变只是影响了元素的一些外观之类的时候(例如,背景色,边框颜色,文字颜色等),此时只需要应用新样式绘制这个元素就OK了,这个过程称为Repaint。

    优化:

    (1)简化DOM结构,减少DOM树和渲染树构建成本;

    (2)JS放在底部,CSS放在顶部

    (3)减少DOM相关操作,如使用DocumentFragment、修改class name而不是style、减少重排和重绘操作

  • 相关阅读:
    HTTP 和 HTTPS
    HTTP 协议
    基础查询
    python编程从入门到实践笔记
    python-32-类的组合与初识继承
    python-31-初识面向对象与自定义类
    python-30-异常处理
    python-29-模块与包导入
    python-28-序列化模块
    python-27-其他常用模块(二)
  • 原文地址:https://www.cnblogs.com/xiaoan0705/p/10435674.html
Copyright © 2011-2022 走看看