参考笔记: https://zhuanlan.zhihu.com/p/...

1.输入地址

2.浏览器查找域名的ip地址

一图知DNS:
image.png

  1. 查看本地硬盘中的hosts文件,看看有没有和这个域名对应的规则。有的话用本地hosts文件(实习的时候有遇到测试环境跟开发环境使用switchhosts配置不同的host的用法)
  2. 本地无,浏览器发送DNS请求给本地DNS服务器,本地的一般是网络接服务器商提供
  3. 本地服务器首先查询它的缓存记录,若缓存中有这条记录,可以直接返回结果。(递归查询),如果没有,则向DNS跟服务器进行查询
  4. 以www.baidu.com.为例,若根服务器.上没有具体对应关系,则告诉本地DNS服务武器,去域服务器.com上进行查询,并给出域服务器地址,然后本地DNS对.com发起请求,如果域服务器上.com也没有,则告诉本地DNS服务器,去下二级域服务器.baidu.com上查找。(迭代过程),最后DNS域名夫区其向域名的解析服务器发起请i去,这是就能收到一个域名和IP地址的对应关系,本地DNS服务器不仅能将IP地址返回给用户电脑,还能将对应关系保存在本地DNS缓存中,下次查询,可直接返回结果,加快网络访问。
    PS: www.baidu.com. .是根服务器,com是一级域服务器,然后baidu.com是二级域服务器

3.浏览器向web服务器发起HTTP请求

拿到域名对应ip地址后,浏览器以一个随机端口(1024<端口<65535)向服务器的web程序(常用httpd,nginx)的80端口发起TCP请求,这个连接请求到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接。建立了TCP连接之后,发起一个http请求。一个典型的 http request header 一般需要包括请求的方法,例如 GET 或者 POST 等,不常用的还有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,一般的浏览器只能发起 GET 或者 POST 请求。   客户端向服务器发起http请求的时候,会有一些请求信息,请求信息包含三个部分:

请求方法URI协议/版本
请求头(Request Header)
请求正文
TCP连接图示:
image.png
TCP断开连接图示
image.png

4.服务器的永久重定向响应

服务器给浏览器响应一个301永久重定向响应,这样浏览器就会访问http://www.baidu.com/而非http://baidu.com/

5.浏览器跟踪重定向地址

现在浏览器知道了 http://www.baidu.com/ 才是要访问的正确地址,所以它会发送另一个http请求。

6.服务器处理请求

经过前面的重重步骤,我们终于将我们的http请求发送到了服务器这里,其实前面的重定向已经是到达服务器了,那么,服务器是如何处理我们的请求的呢?
后端从在固定的端口接收到TCP报文开始,它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。
一些大一点的网站会将你的请求到反向代理服务器中,因为当网站访问量非常大,网站越来越慢,一台服务器已经不够用了。于是将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。

此时,客户端不是直接通过HTTP协议访问某网站应用服务器,而是先请求到Nginx,Nginx再请求应用服务器,然后将结果返回给客户端,这里Nginx的作用是反向代理服务器。同时也带来了一个好处,其中一台服务器万一挂了,只要还有其他服务器正常运行,就不会影响用户使用。

7.服务器返回一个HTTP响应

经过前面的6个步骤,服务器收到了我们的请求,也处理我们的请求,到这一步,它会把它的处理结果返回,也就是返回一个HTPP响应。

HTTP响应与HTTP请求相似,HTTP响应也由3个部分构成,分别是:

  • 状态行
  • 响应头(Response Header)
  • 响应正文

8.浏览器显示 HTML

在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了,浏览器是如何把页面呈现在屏幕上的呢?

解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树

浏览器在解析html文件时,会”自上而下“加载,并在加载过程中进行解析渲染。在解析过程中,如果遇到请求外部资源时,如图片、外链的CSS、iconfont等,请求过程是异步的,并不会影响html文档进行加载。

解析过程中,浏览器首先会解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)。

DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。

页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。

当文档加载过程中遇到js文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程。因为JS有可能会修改DOM,最为经典的document.write,这意味着,在JS执行完成前,后续所有资源的下载可能是没有必要的,这是js阻塞后续资源下载的根本原因。所以我明平时的代码中,js是放在html文档末尾的。

JS的解析是由浏览器中的JS解析引擎完成的,比如谷歌的是V8。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如IO读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。

JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)。

9. 浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等)

其实这个步骤可以并列在步骤8中,在浏览器显示HTML时,它会注意到需要获取其他地址内容的标签。这时,浏览器会发送一个获取请求来重新获得这些文件。比如我要获取外图片,CSS,JS文件等,类似于下面的链接:

图片:http://static.ak.fbcdn.net/rs... CSS式样表:http://static.ak.fbcdn.net/rs... JavaScript 文件:http://static.ak.fbcdn.net/rs...
这些地址都要经历一个和HTML读取类似的过程。所以浏览器会在DNS中查找这些域名,发送请求,重定向等等…

不像动态页面,静态文件会允许浏览器对其进行缓存。有的文件可能会不需要与服务器通讯,而从缓存中直接读取,或者可以放到CDN中


九是我呀
19 声望1 粉丝

希望每写一篇优质文章,工资就涨100元。