这是一个老生常谈的话题,今天我们再来详细想分析一波。
步骤如下:
1.浏览器对用户输入的网址(域名)做初步的格式化检查
2.浏览器对用户输入的网址默认进行http/https补全。
3.浏览器将网址通过DNS协议解析成具体的IP地址
PS:DNS(Domain Name System),域名系统,是一个联机分布式数据库系统,并采用客户服务器方式,DNS大多数名字都在本地解析,少量解析需要在网络上,因此它的效率很高。IP地址的解析是由许多的域名服务器程序共同完成的。
在这个步骤中,又细分以下几个步骤:
1).查询浏览器的DNS缓存,可以使用 chrome://net-internals/#dns 来查看,如果没有对应IP,则进入下一步
2).查询操作系统的DNS缓存,以Windows系统为例,可以在命令行下使用 ipconfig /displaydns 来进行查看,如果没有对应IP,则进入下一步
3).读取hosts文件(位于C:\Windows\System32\drivers\etc),查看有没有该域名对应的IP地址,如果没有,则进入下一步
此时已经确保了你的本机的DNS里没有对应IP了,接下来就要通过网络去查找了。
4).联网向浏览器发起一个DNS的系统调用,向本地配置的ISP(Internet Service Provide,即互联网服务提供者,可以理解为运营商)发起域名解析请求,通过UDP协议向DNS服务器的53端口发起请求,这个请求是递归的请求,也就是的DNS服务器必须得提供给我们该域名的IP地址,ISP的DNS服务器首先查找自身的缓存,找到对应的条目,且没有过期,则解析成功。如果没有找到对应的条目,则ISP的DNS代我们的浏览器发起迭代DNS解析请求,它首先是会找根域的DNS的IP地址,这个DNS服务器都内置13台根域的DNS的IP地址(这里的13台根域名服务器其实并不真是13台,而是13个ip地址,采用任播技术,我们可以在全球设立这些ip的镜像站点,你访问到的ip并不是唯一的那台主机),找到根域的DNS地址后,就会向其发起请求,例如www.cnblogs.com这个域名(www是三级域名,cnblog是二级,com是顶级),根域发现这是一个顶级域com域的一个域名,于是就告诉ISP的DNS我不知道这个域名的IP地址,但是我知道com域的IP地址,你去找它,于是ISP的DNS就得到了com域的IP地址,又向com域的IP地址发起了请求,请问www.cnblogs.com这个域名的IP地址是多少?com域这台服务器告诉运营商的DNS我不知道www.cnblogs.com这个域名的IP地址,但是我知道www.cnblogs.com这个域的DNS地址,你去找它去,于是ISP的DNS又向www.cnblogs.com这个域名的DNS地址(这个一般就是由域名注册商提供的,像万网,新网等)发起请求(请问www.cnblogs.com这个域名的IP地址是多少?),这个时候cnblogs.com域的DNS服务器一查,果真在我这里,于是就把找到的结果发送给ISP的DNS服务器,这个时候运营商的DNS服务器就拿到了www.cnblogs.com这个域名对应的IP地址,并返回给Windows系统内核,内核又把结果返回给浏览器,终于浏览器拿到了www.cnblogs.com对应的IP地址,该进行一步的动作了。
4.发起TCP的3次握手
大概的过程就是:
- 第一次握手: A给B打电话说,你可以听到我说话吗?
- 第二次握手: B收到了A的信息,然后对A说: 我可以听得到你说话啊,你能听得到我说话吗?
- 第三次握手: A收到了B的信息,然后说可以的,我要给你发信息啦!
在三次握手之后,A和B都能确定这么一件事: 我说的话,你能听到; 你说的话,我也能听到。 这样,就可以开始正常通信了。
5.发送Http请求
Http请求报文携带各种头部信息,大致分为三个部分:请求行、请求头、请求体。
请求行一般包括:服务器协议版本,状态码:
状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求。
请求头一般包括:此次响应的时间、此次响应返回的文件长度、文件类型等等
请求体一般包括:服务器返回给客户端的文件、数据等(当请求时POST的时候才会有请求体)
6.服务器处理后响应给客户端HTML文件
7.浏览器解析HTML代码。
浏览器拿到html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源(HTTP的版本要为1.1),下载资源的顺序就是按照代码里的顺序,但是由于每个资源大小不一样,而浏览器又多线程请求请求资源,所以显示的顺序并不一定是代码里面的顺序。
如果浏览器在请求静态资源时(在未过期的情况下),向服务器端发起一个http请求(询问自从上一次修改时间到现在有没有对资源进行修改),如果服务器端返回304状态码(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地的该资源的缓存文件。
8.浏览器渲染页面
渲染的过程大致分为:
- 转换: 浏览器从磁盘或网络读取 HTML 的原始字节,并根据文件的指定编码(如 UTF-8)将它们转换成各个字符。
- Tokenizing: 浏览器将字符串转换成 W3C HTML5 标准规定的各种tokens,例如,“”、“”,以及其他尖括号内的字符串。每个token都具有特殊含义和一组规则。
- 词法分析: 发出的标记转换成定义其属性和规则的“对象”。
- DOM 构建: 最后,由于 HTML 标记定义不同标记之间的关系(一些标记包含在其他标记内),创建的对象链接在一个树数据结构内,此结构也会捕获原始标记中定义的父项-子项关系:HTML 对象是 body 对象的父项,body是paragraph对象的父项,依此类推。
整个流程最终输出是页面的文档对象模型 (DOM),浏览器对页面进行的所有进一步处理都会用到它。
总结:
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 连接结束
用到的协议:
这部分的知识完全可以写成一本书的厚度,无论从前端,后端,网络,协议各方面都有庞大的知识体系,所以只能对其中最核心的地方做阐释,具体请参见《网络是怎么连接的》这本书。
本文部分参考了
https://www.cnblogs.com/wupeixuan/p/8747918.html
https://www.cnblogs.com/kevin2chen/p/6938021.html
https://segmentfault.com/a/1190000006879700
《图解HTTP》
《计算机网络》教材