Magren

Magren

Idealist & Garbage maker 🛸
twitter
jike

从输入URL到页面展示

最近在准备着前端的面试,这个问题基本是必考题,稍微去网上查阅了一些资料,并且自己整理了下。
总的过程如下:

  • 输入 URL
  • DNS 解析
  • 建立 TCP 链接
  • 发送 HTTP 请求
  • 服务器永久重定向
  • 服务器处理请求并返回一个 HTTP 响应
  • 浏览器显示 HTML
  • 链接结束

输入 URL#

URL 的中文名叫统一资源定位符,用于得到资源的位置和访问方法。
其组成为:协议:// 主机名:端口号 / 路径 /; 参数?查询 #信息片段

DNS 解析#

DNS(域名系统),因特网上作为域名和 IP 地址相互映射的一个分布式数据库,得到主机名对应的 IP 地址的过程就叫做域名解析。
DNS 解析的过程其实就是为了寻找哪台机器上有需要的资源,实际上充当了一个翻译的身份,将输入的网址转换成 IP 地址。
以下是 DNS 的一个查找顺序:

  • 浏览器缓存:向浏览器缓存中读取访问记录
  • 操作系统缓存:查找在系统运行内存中的缓存
  • host 文件:查找本地硬盘的 host 文件
  • 路由器缓存:部分路由器会缓存访问过的域名
  • ISP(互联网服务提供商)DNS 缓存:在本地查找不到的情况下,ISP 会在当前服务器的缓存中查找
  • 根 DNS 服务器:根域名收到请求,判断是哪台服务器管理,并返回顶级 DNS 服务器的 IP 给请求者。

在查找完以后本地 DNS 服务器向域名的解析服务器发起请求,本地服务器将 IP 地址返回给电脑,并将对应关系保存在缓存中。

拓展:
DNS 的查询方式:

  • 递归:局部 DNS 服务器负责向其他 DNS 服务器查询(一般先向该域名的根域服务器查询,接着一级一级向下查询),结果返回给局部 DNS 服务器后再由其返回个客户端。
  • 迭代:局部 DNS 服务器把能解析该域名的其他 DNS 服务器的 IP 地址给客户端 DNS 程序,再由该程序向这些 DNS 服务器查询(用于局部 DNS 服务器不能回答客户机 DNS 查询时)。

DNS 优化方法:

  • DNS 缓存
  • DNS 负载均衡
    • 为啥需要:当每次请求的资源都在同一台机器上时,机器可能承受不过来而崩掉。
    • 原理:为一个主机名配置多个 IP 地址,在应答查询饿时候对每个查询以 DNS 文件中记录的 IP 地址按顺序返回不同的结果,将访问引导到不同的机器上去。

建立 TCP 链接#

拿到 IP 地址后就是通过三次握手来建立 TCP 链接了。

  • 第一次握手:客户端发送SYN(同步序列编号)包到服务器,并且进入SYN_SENT状态,等待服务器确认。
  • 第二次握手:服务器收到 SYN 包后确认,同时自己也发送一个 SYN 包,即SYN+ACK 包,服务器进入SYN_RECE状态
  • 第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送一个确认包 ACK,发送完毕后客户端和服务器进入ESTABLISHED状态。

拓展:
为啥三次握手:为了防止已经失效的链接请求报文突然传送到了服务端因而产生错误。

发送 HTTP 请求#

建立 TCP 连接后客户端发起 HTTP 请求,HTTP 报文包含三个部分:

  • 请求行:请求方法 + URL + 协议 / 版本
  • 请求报头:传递请求的附加信息和客户端自身的信息
  • 请求正文:需要传递的数据

服务器永久重定向#

服务器给浏览器响应一个 301 永久重定向响应,例如访问http://google.com/ 会自动跳转到 http://www.google.com/

目的

  • 这样就会把访问带 www 的和不带 www 的地址归到同一个网站排名下,网站在搜索链接的排名下就不会降低。
  • 用不同的地址会导致缓存的良好性变差,一个页面有多个名字的时候可能会在缓存中出现多次。

服务器处理请求并且返回 HTTP 报文#

后端从固定的端口接收到 TCP 报文后,会对 TCP 进行处理,对 HTTP 协议进行解析,按照报文格式进一步封装成 HTTP Request 对象,供上层使用。
HTTP 响应由 4 个部分组成:

  • 状态行:协议版本、状态代码、状态描述
  • 响应头:由键值对组成,每行一对,用 “:” 分割
  • 空行: 分割请求数据
  • 响应正文

拓展:
在大一点的网站中会将请求到反向代理中,将同一应用部署到多台服务器上,将大量用户请求分配给多台机器处理。
即客户端先请求到 Nginx,Nginx 再请求应用服务器,最后将结果返回客户端。

浏览器显示 HTML#

浏览器显示 HTMl 是一个边解析边渲染的过程,大致的过程为:

  • 解析 HTML 文件构建 DOM 树
  • 解析 CSS 文件构建渲染树
  • 浏览器开始布局渲染树并将其绘制到屏幕上

拓展:
关于 reflow (回流) 和 repaint (重绘)

  • DOM 节点中的各个元素都是以盒模型的形式存在,浏览器计算其位置、大小等属性的这个过程称之为 reflow。
  • 当这些属性都确定下来后,浏览器开始绘制内容,这个绘制的过程称之为 repaint。

reflow 和 repaint 在页面首次加载的时候是肯定要经历的,但是这两个过程都是十分消耗性能,应该尽可能减少。
js 解析以及执行机制:
当解析过程中遇到 JS 文件时,HTML 文档会挂起渲染的线程,然后等待 js 文件加载并且解析完毕(由于 js 有可能会修改 DOM,例如 document.write),故平时 js 代码也是放在 html 的末尾。
js 解析是由浏览器中的 js 解析引擎完成,js 是单线程运行,但是像 IO 读写等任务比较耗时,所以需要一种机制可以先执行排在后面的任务,即同步任务和异步任务。
js 的执行机制可以看做成一个主线程 + 一个任务队列。
同步任务是放在主线程上的任务,在主线程上形成一个栈;
异步任务是放在任务队列中的任务,有了运行结果就会在任务队列中放置一个事件;
脚本先运行栈,然后从任务队列中提取事件,运行里面的任务。
这个过程不断循环,也被称为事件循环

链接结束#

现在页面为了优化请求耗时,一般都会持续着 TCP 的链接,而 TCP 链接断开的时机是当前页面关闭的时候。
接下来就是四次挥手断开 TCP 链接:

  • 主机发送一个 FIN,主机进入FIN_WAIT_1状态。
  • 服务端收到 FIN 后,发送一个 ACK 给主机,确认序号为收到序号 + 1,服务端进入CLOSE_WAIT状态。
  • 服务端发送一个 FIN 报文,用来关闭数据传送,并且进入LAST_ACK状态。
  • 主机收到 FIN 后,进入 TIME_WAIT 状态,接着发送一个 ACK 给服务端,确保服务端收到自己的 ACK 报文后进入CLOSED状态
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。