常见的面试题‘输入URL并回车后发生了什么’,你可能答漏了

1,106 阅读3分钟

大部分人在回答这个问题时会从 DNS 解析开始说起,这样回答的确没有问题,因为实际存在很多特殊情况,不可能回答的面面俱到。但实际上 W3C 已经将浏览器的导航过程写进了规范,如果我们能按照 W3C 规范回答这个问题,说不定能在面试中脱颖而出。

让我们来看看 Navigation Timing 规范中是如何定义浏览器导航过程的,如下图所示分别是:卸载提示、重定向、应用程序缓存、DNS 解析、TCP 握手、HTTP 请求处理、HTTP 响应处理、DOM 处理、文档装载完成。

可以看到在 DNS 解析之前还有3个过程:页面卸载提示,重定向,应用程序缓存。大部分前端同学可能会忽略这3个过程,让我们来一一探索。

Prompt for unload 卸载提示

如果在你是在非空白的页面输入的URL,浏览器需要先卸载当前的页面,并触发 beforeunload 和 unload 事件。

使用下面的方式可以让旧页面在卸载前对用户进行提示。

window.addEventListener('beforeunload', function(e){
    e.returnValue = '关闭提示'
})

使用上面的方法有以下几点需要注意:

  • 从Firefox 4、Chrome 51、Opera 38和Safari 9.1开始,浏览器使用通用的确认信息来代替事件返回的字符串。
  • 如果你没有与旧页面发生过交互,浏览器会忽略你的自定义beforeunload事件。
  • 从 HTML5 开始,该事件中执行以下方法会忽略:window.showModalDialog(), window.alert(), window.confirm(), window.prompt()。

Redirect 重定向

这里的重定向指的是浏览器内部执行的重定向,不需要建立网络链接。

301 永久重定向

浏览器会缓存首次访问的 301 重定向(没有设置 no cache 时)。

例:访问 vip.com (非首次访问),浏览器会由于缓存直接将你的请求重定向到 http://www.vip.com

细心的你会发现,301 缓存重定向之后,http://www.vip.com 又会被 302 重定向到 https://www.vip.com, 但这是在 TCP 连接之后的事了。当然 302 重定向也可以被缓存,这需要服务端做相应的缓存配置。

HSTS

HSTS(HTTP Strict Transport Security) 是一套网络安全策略机制,当使用该机制时,浏览器将通过重定向的方式强制使用 https 与网站通信。

例:访问 www.baidu.com (非首次访问), 浏览器会根据 HSTS 记录直接将请求重定向到 https://www.baidu.com

chrome 浏览器中,可以在 chrome://net-internals/#hsts 查看浏览器的 HSTS 记录。

Application Cache 应用程序缓存

HTML5 提供了一种离线缓存机制,使用该机制后用户即使在离线状态下也能浏览网站内容。使用方式是在 <html> 元素上添加 manifest 属性:

<html manifest="demo.appcache">
<body>
The content of the document......
</body>
</html>

demo.appcache 是你的缓存配置文件,一个简单的配置如下所示:

CACHE MANIFEST
demo_time.js
logo.png

添加了 manifest 属性后,页面的加载过程将会被改变:

  1. 浏览器直接从缓存中加载文档与相关资源,不会访问网络。
  2. 浏览器检查清单文件列出的资源是否在服务器上被修改。
  3. 如果清单文件被更新了, 浏览器会下载新的清单文件和相关的资源。

例:这里借用下菜鸟教程的例子,打开该页面 ,然后断开网络刷新页面,你会发现页面仍可访问。

然而,由于设计不佳,Application Cache 被认为很难在实践中使用(参见 Application Cache Is A Douchebag),目前相关的 web 标准已删除该特性,浏览器也将逐渐移除该功能。

MDN上建议使用 Service Workers 代替 Application Cache。前者相对于后者来说比较复杂,但更加灵活,解决了后者存在的一些不足。

例:访问 www.taobao.com, 然后断开网络刷新页面,你会发现页面仍可访问。