从浏览器地址栏输入url到请求返回发生了什么
1. DNS解析,将域名解析成IP地址
URL
URL(Uniform Resource Locator),统一资源定位符,用于定位互联网上的资源,俗称网址.
protocol://host.domain:port/path/filename
- protocol:因特网的协议类型,常见的协议有:http、https、ftp、file,其中最常见的是http,https则是在http的基础上进行加密
- host:定义域主机,http默认主机为www
- domain:因特网域名
- port:主机端口号
- path:服务器上路径
- filename:文档/资源名称
IP地址
IP地址是指互联网协议地址.它是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异.IP地址是一个32位的二进制数,如127.0.0.1就是本机地址. 域名就相当于是IP地址的代号,它的作用就是便于记忆和沟通一组服务器的地址.
DNS
DNS (Domain Name System),因特网作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用直接记忆能被机器直接读取的IP数串.
DNS域名
- 根域:DNS域名使用时,规定由尾部句点(.)来指定名称,位于根或者更高级别的域层次
- 顶级域:用来展示某个国家/地区/组织使用的名称类型
- 第二层域:个人或组织在Internet上使用的注册名称
- 子域:已注册的二级域名的派生域,俗称网站
- 主机:通常情况下,上文中的host,DNS域名的最左侧标签,标示网络上的特定计算机
DNS负载均衡
当一个网站的用户足够多时,假如每次的请求都达到同一台机器上,那么就可能导致机器随时会宕机,这就需要采用DNS负载均衡技术,在DNS服务器中为同一个主机配置多个IP地址,在应答DNS查询时,DNS服务器对每个请求将以主机的DNS文件中IP地址按顺序返回不同的查询结果,将客户端的访问引导到不同的机器上,使得不同的客户端访问到不同的机器,从而达到负载均衡的目的.(机器的负载量、地理位置等)
域名解析
DNS协议提供通过域名查找IP地址,或逆向从IP地址反查域名的服务,而通过域名查找能被机器直接读取的IP数串的过程被称为域名解析.当局部DNS服务器不能回答主机的DNS查询时,它就需要向其他DNS服务器查询,此时可以分为两种方式:递归查询、迭代查询
- 递归查询:当DNS服务器不能回应主机的查询时,DNS服务器会向其他服务器发起查询,一般是向该域名的根域服务器查询,再由根域服务器一级一级向下查询,直到得到查询结果再返回给DNS服务器,再由DNS服务器返回给主机.
- 迭代查询:当DNS服务器不能回应主机的查询时,DNS服务器会把能够解析该域名的其他DNS服务器的IP地址返回给主机,由主机的DNS程序向这些DNS服务器发起查询,直到找到查询结果.
浏览器如何通过域名去查询IP
- 根据浏览器的缓存查找IP
- 如果浏览器的缓存中没有查找到的域名,那么就去本地操作系统中的host文件去查找
- 如果本地的host文件中没有找到,那么就去路由器中查找DNS缓存
- 如果路由器中没有DNS缓存,那么就去网络供应商的DNS服务器中查找
- 如果网络供应商的DNS服务器中查找不到,那么就会向跟服务器中查找(递归查询)
- 如果网路供应商的DNS服务器查找不到,告知你向其他域服务器查找(迭代查询)
- 找到可以解析IP地址的DNS服务器后,返回给本地DNS服务器地址
- 本地向DNS服务器发起请求,获取域名对应的IP地址,并将IP地址和域名的映射关系缓存起来,方便下次的访问
2. 建立连接,发出请求
拿到域名对应的IP地址后,浏览器会以一个随机端口(1024<端口<65535)向服务器的web程序80端口发起TCP的连接请求,这个请求到达服务端后,进入到网卡,经过内核的TCP/IP协议栈(用于识别连接请求,解封包),还有可能经过防火墙的过滤,到达WEB程序,最终建立TCP/IP连接.
TCP三次握手(防止已失效的连接请求报文段突然传送到服务端,因而产生错误)
- 客户端将标志位SYN置为1,随机产生一个值为seq=J(J的取值范围=1234567)的数据包到达服务器,客户端进入SYN_SENT状态,等待服务端确认.
- 服务端收到数据包后由标识位SYN=1知道客户端请求建立连接,服务端将SYN和ACK都置为1,ack=J+1,随机产生一个seq=K,并将该数据包发送给客户端确认连接请求,服务端进入SYN_RCVD状态
- 客户端收到确认,检查ack是否为J+1,ACK是否为1,如果正确则将标识位ACK置为1,ack=K+1,并将该数据包发送给服务端,服务端检查ack是否为K+1,ACK是否为1,如果正确,则建立连接成功,客户端和服务端进入ESTABLISHED状态,完成三次握手,随后客户端和服务端开始传送数据
OSI七层通信模型
- 应用层:为应用程序提供服务并规定应用程序中通信的相关细节,包括文件传输、电子邮件、远程登录等协议
- 表示层:将应用处理的信息转换成适合网络传输的格式,或将下一层的数据转换成上层能够处理的格式,主要负责数据格式的转换
- 会话层:负责建立和断开通信连接(数据流动的逻辑通路)以及数据的分割等数据传输相关管理
- 传输层:TCP,可靠传输,只在通信双方节点上进行处理,而无需在路由器上处理
- 网络层:IP,将数据传输到目标地址.主要负责寻址和路由选择
- 数据链路层:负责物理层面的互联、节点之间的通信传输
- 物理层:负责0、1比特流与电压的高低、光的闪灭之间的转换
HTTP请求
请求报文由请求行、请求头、请求体三部分组成,POST /chapter/user.html HTTP/1.1
- 请求行: 包含请求方法、URL、协议版本
- 请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE、PATCH、TRACE
- URL即请求地址
- 协议版本即http版本号
- 请求头:包含请求的附加信息,由关键字/值对组成,每行一对,关键字和值用:隔开,包括许多有关的客户端环境和请求正文的有用信息:Host:主机名、keepalive:持久连接、User-Agent:请求发出者
- 请求体:承载多个参数的请求数据,包含回车符、换行符、请求数据,并不是所有的请求都有请求数据
3. 服务器处理请求
经过上面的步骤,我们的Url请求到达服务器,服务器根据接收到的Http请求消息中内容进行处理,请求消息中请求行包含请求方法和URL,服务器会根据这些内容向客户端返回数据,如:method:GET,URI:*.html,服务器将会从文件中读取html,将其作为响应消息返回.但是URI指定的条件内容不仅限于html,也可能是一个程序,如:ajax请求,对应的可能是服务器的一个Controller,经过程序中的一些业务逻辑从数据库中查询或者更新数据,最后返回结果.
MVC后台处理阶段
- View(视图):提供给用户操作界面,是程序的外壳
- Controller(控制器):根据用户从视图层输入的指令,从模型层选取数据,然后对其进行操作,产生最终结果.控制器属于管理者角色,从视图接收请求并决定调用哪个模型来处理请求,然后确定哪个视图去显示返回的数据
- Model(模型):负责数据的交互,一个模型能为多个视图处理数据
Http响应报文
响应报文由响应行、响应头部、响应主体三部分组成.
- 状态行:包含协议版本、状态码、状态描述,
HttpVersion StatusCode ReasonPhrase如:HTTP/1.1 200 OK- 1xx:指示消息-表示请求已接收,继续处理
- 2xx:请求成功-表示请求已被成功接收、处理、接受
- 3xx:重定向-要完成请求必须进行下一步操作
- 4xx:客户端错误-请求有语法错误或者请求无法实现
- 5xx:服务端错误-服务器未能实现合法请求
- 响应头部:包含响应报文的附加信息,由 名/值 对组成
- 响应主体:包含回车符、换行符、响应数据,并不是所有的响应报文都有响应数据
网络代理
-
正向代理:当客户端无法访问外部资源时,需要一个服务器代替客户端去访问服务器
- 访问原来无法访问的资源,VPN
- 可以做缓存,加速访问资源
- 对客户端访问授权,上网认证
- 记录访问记录,对外隐藏用户信息
-
反向代理:当客户端请求服务端时,需要由一个服务器接收客户端的请求,然后把请求转发给内部的服务端上
- 负载均衡
- 保证内网安全,阻止web攻击.大型网站,通常将反向代理作为公网访问地址,web服务器是内网
4. 浏览器解析渲染界面
浏览器在解析html文件时,会“自上而下”加载,并在加载过程中进行解析渲染.在解析过程中,如果遇到请求外部资源时,如图片、外链的CSS、iconfonts等,请求过程时异步的,并不会影响html文档进行加载(类似上述步骤,不像动态页面,静态文件会被浏览器缓存,有的文件可能会不需要与服务器通讯,而从缓存中直接读取,或者可以放在CDN中).
- 根据HTML解析出DOM树
- 根据HTML的内容,将标签按照结构解析成为DOM树.DOM树的解析过程是一个深度优先遍历,即先构建当前节点的所有子节点,再构建下一个兄弟节点
- 在构建DOM过程中,若遇到script标签,则DOM树的构建会暂停,直到脚本执行完成.因为JS有可能会修改DOM,这意味着在JS执行完成前,后续所有资源的下载可能是没有必要的,这是JS阻塞后续资源下载的根本原因.
- 根据CSS解析CSS规则树
- 解析css规则树时,JS暂停执行,直至CSS规则树就绪
- 浏览器在CSS规则树生成之前不会进行渲染
- 结合DOM树和CSS规则树,生成渲染树
- DOM树和CSS规则树全部准备好后,浏览器才会开始构建渲染树
- 精简CSS 可以加快CSS规则树构建,从而加快页面响应速度
- 根据渲染树,计算每一个节点的信息
- 布局: 通过渲染树中渲染对象的信息,计算每一个渲染对象的位置和尺寸
- 根据计算好的信息绘制页面
- 绘制阶段,系统会遍历呈现树,并调用呈现器的paint方法,将呈现器的内容展示在屏幕上
重绘 和 回流
页面在首次加载时,必然会经历回流和重绘,这个过程中是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿.回流必然引起重绘,重绘不一定引起回流
- 回流: 当渲染树中的一部分或全部因为元素的规模尺寸、布局、隐藏等改变时,就需要重新计算布局信息
- 重绘: 当渲染树中的元素需要更新属性,这些属性只影响元素的外观、风格而不会影响布局
JS解析
JS解析是由浏览器中的JS解析引擎完成的.JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始.但又存在某些任务比较耗时,如IO读写等.所以需要一种机制可以先执行排在后面的任务:同步任务、异步任务 JS执行机制可以看作是在一个主线程加上一个任务队列.同步任务就是放在主线程上执行的任务,异步任务就是放在任务队列的任务.所有的同步任务都是放在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列提取事件,运行任务队列的任务,这个过程是不断重复的,所以又叫做事件循环(Event Loop)
5.断开连接
当数据传送完毕后,需要断开TCP连接
- 客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态
- 服务端收到FIN后,发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),服务端进入CLOSE_WAIT状态
- 服务端发送一个FIN,用来关闭服务端和客户端的数据传送,服务端进入LAST_ACK状态
- 客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送ACK给服务端,确认序号为收到序号+1,服务端进入CLOSED状态,完成四次挥手
为什么建立连接是三次握手,而关闭连接是四次挥手
因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端.而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据但是还能接受数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此ACK和FIN一般都分开发送.