Skip to content

Latest commit

 

History

History
43 lines (37 loc) · 6.1 KB

yong-hu-shu-ru-url-dao-ye-mian-zhan-xian-de-guo-cheng.md

File metadata and controls

43 lines (37 loc) · 6.1 KB

用户输入 url 到页面展现的过程

这是一道很经典的面试题了,考察点也是很多,dns 解析、http、浏览器渲染的过程等等,github 上也有个仓库详细的解释了这个过程,what-happens-when,所以我按照自己的思路再提炼一次

  1. 首先,计算机是不会和人打交道的,那么要让�它打交道我们需要输出和输入设备,这里我们需要输入设备键盘、鼠标和输出设备显示器,当然了我们还需要一个浏览器,浏览器是一个软件,是一个可以运行在计算机上供用户浏览网页的软件

  2. 当我们输入 url 的时候,发生了什么?我们在按键,键盘有按下和抬起的区别,当我们按下的时候系统中断,并且�键盘驱动取得当前按键的扫描码发送给 CPU,CPU 通过对应表找到显示字符并发送给浏览器,浏览器显示该字符

    • 按下和抬起的时候键盘电路快速的开和关,所以避免误判,这里会做防抖处理,并且按下后长时间不放会做多次按键处理
    • 系统中断这个有点像 angularJs 的脏值检测,不是通过轮询来实现数据检测,而是在特定的事件发生后进入检测,系统中断也是如此,不然的话�要一直检测输入设备的状态 low
    • 对应表是扫描码和显示字符的对应
    • 输入过程中�浏览器会根据输入历史和建议显示相近的字符供用户选择
  3. url 输入完毕后按下回车,这时候浏览器会解析 url 并验证 url 的正确性,如果协议或域名不正确�则会�传递给设置的搜索引擎,正确的话先去 HSTS list 中匹配该网站是否只使用 https 连接

    • 解析 url 步骤会转化非 ASCII �字符
    • Chrome HSTS list 查看:地址栏输入 chrome://net-internals/#hsts
    • 不在 HSTS list 中也可以通过设置请求头来实现 HSTS 访问: add_header Strict-Transport-Security: max-age=31536000; includeSubDomains; preload;
  4. 开始解析域名,也就是常说的 DNS,DNS 做过网站的朋友应该是知道的,�网站是要买域名的,但是�网络根本不知道你的域名和服务器对应关系,所以一般买完域名要域名解析,让网络知道 aaa.com->10.10.10.10,域名其实相当于 alias,我们想要找到目标服务器只能通过 ip,所以会先检查浏览器的 DNS 缓存,如果找到了直接拿到 ip 访问网站,如果没有,去系统缓存中查找,没找到会去你的路由缓存或者 ISP 服务商缓存中找,如果还没找到,去根域名服务器进行递归搜索

    • Chrome DNS 缓存: chrome://net-internals/#dns
    • 系统缓存包括 hosts 文件,hosts 每个系统存放的位置是不同的,但是打开都能看到一个域名和 ip 对应关系,也可以自己设置,开发人员�应该很熟悉了
    • ISP 服务商就是你的网络服务提供商,电信啊长城�啊这些,长城辣鸡不解释,�npm install� 能用算我输
    • 全球有13组根域名服务器(名字 A 至 M),�离我们最近的在日本
  5. 拿到 ip 后开始 http 请求,http 是应用层的协议,我们要想进行网络连接需要传输层的协议 TCP ,建立 TCP 连接就到了我们熟悉的三次握手了,�三次握手后客户端和服务端建立了 TCP 连接,可以传输数据了,数据传输完成后要关闭连接,需要四次�挥手

    • 计算机的世界里是很注重规范的,规范其实就是约定,�和服务器建立网络连接也是,要遵循约定,所以 http、ftp 这些其实都是名词,都是约定的名词,以后还可能会有 httpa、httpb 都说不定,至于为什么叫 http,英文缩写咯
    • TCP 和 UDP 其实区别就在于是否面向�连接, UDP 不管三七二十一拿到数据就干��,TCP 需要建立连接并且收发确认,所以 UDP 的传输效率是比 TCP 要高的
    • 三次握手:
      • 第一次握手客户端�发出连接请求报文段,这时首部中的同步位 SYN 置为1,同时初始序号 seq = x,这时客户端进入 SYN-SENT 状态
      • 第二次握手服务端收到连接请求报文段,将 SYN 和 ACK 都置为1,并且确认 ack = x + 1,同时也初始化序列号 seq = y,这时服务端进入 SYN-RCVD 状态
      • 第三次握手客户端收到服务端的确认后,将 ACK 置为1,并且确认 ack = y + 1,而自己的初始序号 seq = x + 1,这时 TCP 连接建立,客户端和服务端进入 ESTABLISHEN 状态
    • 四次�挥手:
      • 第一次挥手数据传输完毕,客户端向服务端发送连接释放报文段�,将首部 FIN 置为1,初始序号 seq = x,这时客户端进入 FIN-WAIT-1 状态
      • 第二次挥手服务端收到后将首部 ACK 置为 1,并且确认 ack = x + 1,初始序号 seq = y,这时服务端进入 CLOSE-WAIT 状态,TCP 属于半关闭状态,因为要确认服务端这边也没有数据要发送了
      • 第三次挥手客户端进入 FIN-WAIT-2 状态,等待服务端发送连接释放报文段,这时候�服务端没有数据发送,服务端将首部 FIN、ACK 置为1�,初始序号 seq = n,确认 ack = x + 1,这时服务端进入 LAST-ACK 状态
      • 第四次挥手客户端收到后将首部 ACK 置为1�,初始序号 seq = x + 1,确认 ack = n + 1,进入到 TIME-WAIT 状态,经过 2MSL 后�客户端进入 CLOSED 状态
    • 这里看到的 SYN、ACK、MSL、FIN 都是啥?
      • MSL - Maximum Segment Lifetime 的英文缩写,可译为最长报文段寿命,它是干什么的?它的值是用来确认 TIME-WAIT 状态的周期( MSL 的两倍)
      • SYN - Synchronous 的英文缩写,表示建立连接
      • ACK - Acknowledgement 的英文缩写,表示响应连接
      • FIN - Finish 的英文缩写,表示关闭连接
      • seq - Sequence Number 的英文缩写,表示序号
      • ack - Acknowledgment Number 的英文缩写,表示确认号
      • TCP 会话的每一段都会包含 seq,seq 初始是随机的,ack 是已经成功接收到的数据字节序号 + 1,换个角度 ack �就是下次要接收数据的 seq