浏览器输入一个url以后发生了什么事情?

122 阅读6分钟

解析Url为ip地址

  1. 查看本地存储,是否存储了该url对应的ip地址,如果有则直接使用,并发送请求(浏览器缓存=>系统缓存=>路由器缓存=>host记录)
  2. 如果本地没有存储,那么就会向上去本地DNS服务器查找
  3. 如果本地DNS服务器也无法查询到的话,就继续进行迭代查找(本地=>根域名服务器=>顶级域名服务器=>权威域名服务器)直到找到目标ip地址

发起tcp连接

  1. 调用socket接口发起tcp建立请求
  2. tcp三次握手建立连接
    • 客户端调用socket.connect()函数,发送包含SYN标志位的数据包给服务端(第一次握手)
    • 服务端收到带有SYN标志位的数据包,知道这是要建立连接,于是也组建一个数据包(包含SYN、ACK,ACK用于表示确认接收到了客户端发送的数据包),发送给客户端(第二次握手)
    • 客户端组建数据包并设置ACK字段发送给服务端,客户端进入establish状态
    • 服务端接收到数据包,确认无误后也进入establish状态,这时连接就建立成功了
  3. 发起http请求:
    • 如果是https请求则还需建立SSL/TSL连接: image.png 在这之后就可以进行愉快的请求啦
  4. 开始发送请求后就涉及到缓存:
    • 首先浏览器查看本地是否有缓存,如果没有则直接向服务器请求数据
    • 如果有则查看Cache-control或expires是否过期,如果没过期则直接使用本地数据
    • 过期了则向服务器发送请求并携带上if-none-matched或if-modified-since字段,如果服务器认定未过期则返回304,加载本地缓存
    • 如果过期了则返回200以及新的数据

拿到html页面

走到这一步,我们要进入浏览器的内核看看了
浏览器是多进程的,分为以下几个进程:

  • 浏览器进程:浏览器进程负责控制浏览器标签导航栏,以及和其他进程进行协调工作
  • 缓存进程:
  • 网络进程:负责发起网络请求
  • GPU进程:负责界面渲染
  • 插件进程:负责控制网站插件(如flash,不是chrome市场中下载的插件)
  • 渲染器进程:渲染每个tab标签内的所有内容(默认情况下每个标签页都会有一个渲染器进程)
  1. 当你在浏览器地址栏输入内容时,浏览器的UI线程会识别你输入的内容,如果访问的是网址则会启动网络线程进行url解析一个网络请求,否则则会使用浏览器默认的搜索引擎进行搜索
  2. 检查站点是否为恶意站点
  3. UI线程启动一个渲染器进程进行渲染页面,通过IPC管道将数据传递给渲染器进程
  4. 渲染器主线程开始解析html,构造DOM 流程如下👇
    • 字节流 -> 字符流(html标签) -> Token化 -> 节点 -> DOM
    • 这里浏览器会首先去创建以document为根节点的对象,并在解析过程中不断向DOM树添加节点
    • 在遇到link标签时就会同步的去下载和解析css,过程和解析html文件类似,最终生成一个CSSOM树
    • 等到DOM和CSSOM都构建完成后,浏览器就会将这两者结合起来构建Render Tree,👇为生成Render Tree的过程
    • 生成Layout Tree(包含每个节点的坐标信息以及边框尺寸),这里伪类会被生成,display属性为none的元素则会被排除
    • 主线程遍历Layout Tree 生成绘制顺序(paint)以及 Layer Tree并将绘制好的信息传递给合成器线程
    • 合成器线程则将绘制好的页面分块发送给栅格线程进行栅格化,最后收集为合成器帧
    • 渲染器进程将帧传送给浏览器进程,接着再传送到GPU,最终渲染到当前页面上
    • 而当滚动页面时则会形成新的帧

然而当浏览器遇到script标签时,则会停止html的解析,先去下载并执行js(注意这里,在执行js前,浏览器会先去渲染一次页面)

tcp 4次挥手断开连接

浏览器状态码

1XX

  • 100:服务端收到了请求头,继续发送请求体(例如post)
  • 101:切换协议(例如切换到HTTP2.0、websocket)

2XX

  • 200:响应成功

3XX

  • 301:永久重定向
  • 302:临时重定向
  • 304:协商缓存

4XX

  • 400:请求出错(例如格式出错)
  • 403:服务器拒绝执行当前请求
  • 404:请求资源不存在
  • 405:请求方法不允许

5XX

  • 500:服务器发生了不可预料的错误
  • 501:服务器不支持当前请求需要的功能
  • 502:网关出错
  • 503:服务器过载
  • 504:网关超时

http1.0、http1.1、http2、http3

http1.0、http1.1

http1.1:

  1. 在http1.0的基础上增加了如delete、options、put等方法
  2. 引入长连接:一个tcp连接可以服用减少了资源的消耗
  3. 引入管道机制:一个连接可以同时发送多个请求,但是要求返回的响应也要按照请求的顺序,所以实用性不高
  4. 增加了协商缓存字段

http2:

  1. 增加多路复用特性,解决http1.1的对头阻塞问题
  2. 请求和响应被划分为不同的帧,首部帧和数据帧,通过流标识符来确定当前帧属于哪个请求
  3. 使用Hpack压缩算法对首部进行了压缩,浏览器和服务器共同保存一张静态只读的表,根据表来判断当前字段对应的意思
  4. 使用二进制传输帧
  5. 服务器推送:根据浏览器发送的请求,预判需要的资源,一起返回给浏览器

http3:

  1. 使用UDP
  2. 使用QUIC协议将握手阶段和TLS握手整合
  3. 使用连接id判断是否为同一个连接,避免多次握手

Vue路由模式

hash模式

通过window.onhashchange()监听URL中hash值的变换,通过location.hash获取当前的hash值

  • 页面不会刷新,更加流畅
  • js中则可以通过location.herf来改变当前的hash值

history模式

js通过history.pushState方法改变URL值,通过window.onpopstate()事件监听URL的变化