经典面试题—在浏览器中输入URL之后发生了什么?
Posted 小王~同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典面试题—在浏览器中输入URL之后发生了什么?相关的知识,希望对你有一定的参考价值。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
总体流程:
- URL解析
- DNS解析:浏览器进行DNS域名解析,得到对应的IP地址
- TCP连接:TCP三次握手
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器根据其请求得到的资源渲染页面
- 断开连接:TCP四次挥手
一、URL解析
URL,统一资源定位符,用于定位互联网上的资源,我们俗称“网址”。
URL遵循以下的语法规则:scheme://host.domain:port/path/filename
- scheme - 定义因特网服务的类型。常见的协议有 http、https、ftp、file,其中最常见的类型是 http,而 https 则是进行加密的网络传输。
- host - 定义域主机(http 的默认主机是 www)
- domain - 定义因特网域名,比如 w3school.com.cn
- port - 定义主机上的端口号(http 的默认端口号是 80)
- path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。
- filename - 定义文档/资源的名称
URL解析的流程为:
1.地址解析:
首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词,并且根据你输入的内容进行自动完成、字符编码等操作。
urlencode 和urldecode (编码和解码)
像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.
比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.
转义的规则:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式。
如上图中,"+" 被转义成了 "%2B"
urldecode就是urlencode的逆过程。
2. HSTS
HSTS 是 HTTP 严格传输安全(HTTP Strict Transport Security) 的缩写。 这是一种网站用来声明他们只能使用安全连接(HTTPS)访问的方法。 如果一个网站声明了 HSTS 策略,浏览器必须拒绝所有的 HTTP 连接并阻止用户接受不安全的 SSL 证书。 目前大多数主流浏览器都支持 HSTS。
由于安全隐患,会使用HSTS强制客户端使用HTTPS访问页面。
3.其他操作
浏览器还会进行一些额外的操作,比如安全检查、访问限制等。
4.检查缓存
二、DNS解析
浏览器不能直接通过域名找到对应的服务器而是要通过IP地址。
IP地址
IP 地址是指互联网协议地址,是 IP Address 的缩写。IP 地址是 IP 协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。IP 地址是一个 32 位的二进制数,比如 127.0.0.1 为本机 IP。
IP协议有两个版本IPv4和IPv6,对于IPv4来说,IP地址是一个4字节,32位的整数。
· 通常也使用 "点分十进制" 的字符串表示IP地址, 例如 192.168.0.1 ; 用点分割的每一个数字表示一个字节, 范围是 0 - 255;
域名解析
DNS协议通过域名查找IP地址,或逆向从IP地址反查域名的服务。
DNS 是一个网络服务器,我们的域名解析简单来说就是在 DNS 上记录一条信息记录。DNS保存了一张域名和与之对应的IP地址的表以解析消息的域名。
浏览器通过域名查询URL对应的IP
基本的步骤:
1.查找浏览器缓存
因为浏览器一般会缓存DNS记录一段时间,不同浏览器的时间可能不一样,一般2-30分钟不等,浏览器去查找这些缓存,如果有缓存,直接返回IP,否则下一步。
2.查找操作系统缓存
浏览器缓存中找不到IP之后,浏览器会进行系统调用(windows中是gethostbyname),查找本机的hosts文件,如果找到,直接返回IP,否则下一步。
3.查找路由器缓存
如果1,2步都查询无果,则需要借助网络,路由器一般都有自己的DNS缓存,将前面的请求发给路由器,查找ISP 服务商缓存 DNS的服务器,如果查找到IP则直接返回,没有的话继续查找。
4.ISP DNS缓存
如果以上步骤还找不到,则ISP的DNS服务器就会进行递归查询,所谓递归查询就是如果主机所询问的本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其他根域名服务器继续发出查询请求报文,而不是让该主机自己进行下一步查询。(本地域名服务器地址是通过DHPC协议获取地址,DHPC是负责分配IP地址的)
5.根域名服务器查询
本地域名服务器采用迭代查询,它先向一个根域名服务器查询。本地域名服务器向根域名服务器的查询一般都是采用迭代查询。所谓迭代查询就是当根域名服务器收到本地域名服务器发出的查询请求报文后,要么告诉本地域名服务器下一步应该查询哪一个域名服务器,然后本地域名服务器自己进行后续的查询。(而不是替代本地域名服务器进行后续查询)
递归查询:一路查下去中间不返回,得到最终结果才返回信息(浏览器到本地DNS服务器的过程)
迭代查询:本地DNS服务器到根域名服务器的查询方式
DNS劫持:域名劫持,通过攻击域名解析服务器或伪造域名解析服务器的方法,把目标网站域名解析到错误的IP地址从而实现用户无法访问目标网站的目的或者蓄意或恶意要求用户指定IP地址的目的。
三、建立TCP连接(三次握手)
在客户端发送数据之前需要发起TCP三次握手建立与服务端的连接,用以同步客户端和服务端的序列号和确认号,并交换 TCP 窗口大小信息。所谓三次握手是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
TCP三次握手的过程
- 第一次握手:建立连接时,客户端A发送SYN包(SYN=1同时选择一个初始序列号seq = x)到服务器B,并进入SYN_SEND状态,等到服务器B确认。
- 第二次握手:服务器B收到SYN包,必须确认客户A的SYN=1,同时自己也发送一个SYN包(SYN=1,确认号是ack = x+1,同时也要问自己初始化一个序列号seq = y),即SYN+ACK包,此时服务器B进入SYN_RECV状态。
- 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ack = y+1,自己的序列号为seq = z),此包发送完毕后,客户端A和服务器B进入ESTABLISHED状态,建立连接完成。
为什么不能用两次握手进行连接?
3次握手完成了两个重要的功能,既要双方做好发送数据的准备工作,也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
如果把三次握手改成仅需要两次握手,死锁是可能发生的。如下图所示,如果计算机Client和Server之间的通信,假定Client给Server发送一个连接请求分组,Server收到了这个分组,并发送了确认应答分组。按照两次握手的协定,Server认为连接已经成功地建立了,可以开始发送数据分组。可是,Client在Server的应答分组在传输中被丢失的情况下,将不知道Server是否已准备好,不知道Server建立什么样的序列号,Client甚至怀疑Server是否收到自己的连接请求分组。在这种情况下,Client认为连接还未建立成功,将忽略Server发来的任何数据分组,Client只等待连接确认应答分组。而Server在发出的数据分组超时后,重复发送同样的数据分组。这样就形成了死锁。
另外三次握手可以防止已失效的连接请求报文段突然又传到了Server,因而产生错误。假定出现一种异常情况,即Client发出的第一个连接请求报文段并没有丢失,而是在某些网络结 点长时间滞留了,一直延迟到连接释放以后的某个时间才到达Server,本来这是一个早已失效的报文段。但Server收到此失效的连接请求报文段后,就误认为是Client又发出一次 新的连接请求,于是就向Client发出确认报文段,同意建立连接。假定不采用三次握手,那么只要Server发出确认,新的连接就建立了,这样一直等待Client发来数据,Server的许多资源就这样白白浪费了。
四、发送HTTP请求
TCP三次握手结束后,开始发送HTTP请求报文 。
HTTP请求报文由请求行、请求头、请求体三个部分组成:
1.请求行包括请求方法、URL、协议版本 ;
请求方法包括:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE;
POST /chapter17/user.html HTTP/1.1
2.请求头包含请求的附加信息,由关键字/值 对组成,每行一对,关键在和值用":"分隔;
HTTP常见的Header:
- Content-Type:数据类型——消息体的格式,告诉对方应该用什么方式进行解析
- Content-Length:消息体的长度
- Host:客户端告知服务器,所请求的资源是在哪个主机的哪个端口上
- User-Agent:声明用户的浏览器版本信息
- referer:当前页面是从哪一个页面条状过来的。
- location:搭配3XX状态码使用,告诉客户端接下来要去哪个访问;
- Cookie:在客户端存储少量的信息,通常用于实现会话session的功能。
3.请求体,可以承载多个请求参数的数据,包括回车符、换行符和请求数据,并不是所有请求都具有请求数据。
关于HTTP请求相关的可以详细浏览必须掌握的HTTP相关知识。
请求的流程
TCP/IP分为四层,在发送数据时,每层都要对数据进行封装:
应用层:发送HTTP请求
在得到服务器的IP地址后,浏览器会开始构造一个HTTP报文
浏览器只能发送GET、POST方法,打开网页使用的时GET方法。
传输层:TCP传输报文
传输层会发起一条到达服务器的 TCP 连接,为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息。
在建立连接前,会先进行 TCP 三次握手。
网络层:IP协议查询Mac地址
将数据段打包,并加入源及目标的IP地址,并且负责寻找传输路线。判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。
数据链路层:以太网协议
以太网协议
根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分:标头:数据包的发送者、接受者、数据类型;数据:数据包具体内容。
Mac 地址
以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了一对一的能力。
广播
发送数据的方法很原始,直接把数据通过 ARP 协议,向本网络的所有机器发送,接收方根据标头信息与自身 Mac 地址比较,一致就接受,否则丢弃。
五、服务器处理请求并返回HTTP响应
服务器处理请求的流程:
服务器是网络环境中的高性能计算机,它侦听网络上的其他计算机(客户机)提交的服务请求,并提供相应的服务,比如网页服务、文件下载服务、邮件服务、视频服务。
而客户端主要的功能是浏览网页、看视频、听音乐等等,两者截然不同。
每台服务器上都会安装处理请求的应用——Web Server 。常见的Web server 产品有apache、nginx等。
web server 担任管控的角色,对于不同用户发送的请求,会结合配置文件,把不同请求委托给服务器上处理相应请求的程序进行处理(例如 CGI 脚本,JSP 脚本,servlets,ASP 脚本,服务器端 javascript,或者一些其它的服务器端技术等),然后返回后台程序处理产生的结果作为响应。
MVC后台处理阶段
后台开发现在有很多框架,但大部分都还是按照 MVC 设计模式进行搭建的。MVC 是一个设计模式,将应用程序分成三个核心部件:模型(model)-- 视图(view)--控制器(controller),它们各自处理自己的任务,实现输入、处理和输出的分离。
首先浏览器发送过来的请求先经过控制器,控制器进行逻辑处理和请求分发,接着会调用模型,这一阶段模型会获取 redis db 以及 MySQL 的数据,获取数据后将渲染好的页面,响应信息会以响应报文的形式返回给客户端,最后浏览器通过渲染引擎将网页呈现在用户面前。
HTTP响应报文
响应报文由响应行、响应头部、响应体三部分组成。
(1) 响应行包括:协议版本、状态码以及状态码描述
状态码规则:
1XX:信息性状态码,接收的请求正在处理
2XX:成功状态码,请求正确处理完毕
3XX:重定向状态码,需要进行附加操作以完成请求
4XX:客户端错误状态码,服务器无法处理请求
5XX:服务器错误状态码,服务器处理请求出错
常见的HTTP状态码:
(2) 响应头包含响应报文的附加信息
- allow:服务器支持哪些请求方法;
- Date:表示消息发送的时间
- server:服务器名字
- Connection:浏览器与服务器之间连接的类型
- Content-Type:表示后面的文档属于什么MIME类型;Servlet默认为text/plain,但通常需要显式地指定为text/html。
- Content-Length:表示内容的长度
- Location:表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。
- Set-Cookie:设置和页面关联的Cookie。
(3) 响应主体包含回车符、换行符和响应返回数据,并不是所有响应报文都有响应数据。
六、浏览器解析渲染页面
浏览器解析渲染页面分为以下5个步骤:
- 根据HTML解析出DOM树
- 根据CSS解析生成CSS规则树
- 结合DOM树和CSS规则树,生成渲染树
- 根据渲染树计算出每一个结点的信息
- 根据计算好的信息绘制页面
转载于:https://www.cnblogs.com/aiqiqi/p/11479185.html#_label5_2
七、断开TCP连接(四次挥手)
TCP四次挥手的过程
当数据传送完毕,需要断开TCP连接,此时发起TCP四次挥手。TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送(报文段4)。发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。被动方发送确认报文,Ack、Seq,表示同意关闭请求。此时主动发起方进入 FIN_WAIT_2 状态,服务器B进入CLOSE_WAIT状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)。被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间2MSL未收到回复,则正常关闭(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)
为什么连接时是三次握手却是四次挥手?
建立连接时:当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。
关闭连接时:当Server端收到FIN报文后,TCP在系统内核实现时,自动响应的ACK;再次发送FIN是应用程序手动的调用close()来关闭连接。程序在关闭连接前,可能需要执行释放资源等前置操作,所以两次不能进行合并,在断开连接的时候就需要四次挥手。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
理论上,四个报文发送完毕,可以直接进入CLOSE状态,但是如果网络不可靠,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK丢失。Server如果没有收到ACK,将不断重复发送FIN片段。
所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。
MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,Client置为CLOSE状态,则结束TCP连接。
以上是关于经典面试题—在浏览器中输入URL之后发生了什么?的主要内容,如果未能解决你的问题,请参考以下文章
经典面试题:一个页面从输入URL到加载显示完成,发生了什么?(转)