输入url后...

浏览器输入url后都做了什么事情

博主还年轻的时候,面试都是这么回答的:
首先找到域名和ip的对应关系,本地host文件照看有没有,有就直接用,没有就去本地DNS服务器查询,本地有就直接用,没有再像根DNS服务器查询,返回对应关系后保存,这时返回的资源浏览器就可以加载了。
现在看来是如此的简单…

细说一下

平时浏览网页可能感受不到,其实这个过程还是蛮复杂的,主要就是这几个过程。

  1. 输入地址
  2. 浏览器查找域名的 IP 地址
  3. 浏览器向 web 服务器发送一个 HTTP 请求
  4. 服务器的永久重定向响应
  5. 服务器处理请求
  6. 服务器返回一个 HTTP 响应
  7. 浏览器显示 HTML
  8. 浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等

输入地址

用户输入URL,浏览器会根据用户输入的信息判断是搜索还是网址。如果是搜索内容,就将搜索内容+默认搜索引擎合成新的URL;如果用户输入的内容符合URL规则,浏览器就会根据URL协议,对一些默认的东西进行补齐,合成合法的URL,然后进行自动完成、字符编码等操作,生成请求报文,现在的浏览器就已经在智能匹配了,比如常用的谷歌浏览器,有时候url没输入完页面都出来了,还会进行安全检查、访问限制等操作。由于安全隐患,会使用 HSTS 强制客户端使用 HTTPS 访问页面。

查浏览器缓存

  1. 浏览器发送请求前,根据请求头或者响应头的expires和cache-control判断是否命中(包括是否过期)强缓存策略,(expires和cache-control是根据资源第一次被请求时保存的)如果命中,直接从缓存获取资源(memory cache/disk cache),并不会发送请求。如果没有命中,则进入下一步。注意这里暂时不会与服务器交流。
  2. 没有命中强缓存规则,浏览器会像服务器发送请求,根据响应头的last-modified和etag判断是否命中协商缓存,如果命中,直接从缓存获取资源。如果没有命中,则进入下一步。

浏览器查找域名的 IP 地址

因为发送 HTTP 请求报文需要依赖下层 TCP 协议,TCP 建立连接并通信是需要 IP 地址 + 端口号 这一对二元组的,端口号可以直接从 URL 中获得,但是 IP 地址需要由 DNS 解析域名来获得。DNS 服务主要功能就是将 URL 中的域名,解析为 IP 地址。
此时如果需要发起请求的主机和被请求的主机是在一个局域网内(比如n个主机通过一个交换机链接),就需要ARP协议发挥作用,因为局域网内主机是通过MAC地址通信。
会先查看自己浏览器有没有缓存此域名的信息,如果没有则进一步查看操作系统缓存(本地host),如果有则直接返回,如果没有则准备发送 DNS 请求,没有再递归查询本地DNS服务器缓存,没有再问根DNS服务器,根DNS服务器迭代查询后提供顶级域名服务器地址,去这里查询,然后顶级域名服务器再给出一个域服务器地址查询,返回域名和ip对应关系给本地DNS,并且本地DNS缓存下这个对应关系。

发请求

  1. 发起TCP连接请求:用上面拿到的拿到域名和ip的对应关系,浏览器以一个随机端口像服务器80端口(http)/443端口(https)发起TCP连接请求,请求到达服务端后经过路由器、网卡等后到达内核的TCP/IP协议栈,最终到达web程序三次握手建立TCP链接。
  2. http请求:可能是get/post等方法,包含请求行,请求头,请求体
  3. 这里服务器有可能返回301、302状态码,需要重定向,这时候又要发送重定向的http请求

服务器处理请求

接受 TCP 报文后,会对连接进行处理,对HTTP协议进行解析(请求方法、域名、路径等),并且进行一些验证:

验证是否配置虚拟主机
验证虚拟主机是否接受此方法
验证该用户可以使用该方法(根据 IP 地址、身份信息等)

浏览器接收数据

浏览器接收到来自服务器的响应资源后,会对资源进行分析。
首先查看 Response header,根据不同状态码做不同的事(比如301、302重定向)。
如果响应资源进行了压缩(比如 gzip),还需要进行解压。
然后,对响应资源做缓存。
接下来,根据响应资源里的 MIME 类型去解析响应内容(比如 HTML、Image各有不同的解析方式)。

浏览器渲染

渲染引擎

  1. html解析
    解码、预解析、符号化、构建dom树(遇到script标签会停止构建,如果js依赖css会等到css规则构建完毕才运行),浏览器还会进行纠错
  2. css解析
    下载的css通过与法规范进行解析,尽量用class或id避免过多的查找
    css权重,!important->行内样式->id->class(伪类)->标签元素(伪元素)
  3. 渲染树
    dom和css树的结合
    原则:(避免html解析出现的问题)
    CSS 资源排在 JavaScript 资源前面
    JS 放在 HTML 最底部,也就是 前
    另外,如果要改变阻塞模式,可以使用 defer 与 async
  4. 布局和绘制+合并渲染
  5. 布局变化或样式变化会回流和重绘
    js引擎
  6. js的执行
    js是解释型语言,运行时才确定变量类型(ts很好地解决了这个问题),运用JIT(及时编译)技术。
    从上到下加载,遇到js会等待js下载完然后执行js,再向下进行。也可以用async 异步加载,加载完就执行,async只能加载外部脚本,不能把js写在script标签里。
上一篇

redux