解析Url为ip地址
- 查看本地存储,是否存储了该url对应的ip地址,如果有则直接使用,并发送请求(浏览器缓存=>系统缓存=>路由器缓存=>host记录)
- 如果本地没有存储,那么就会向上去本地DNS服务器查找
- 如果本地DNS服务器也无法查询到的话,就继续进行迭代查找(本地=>根域名服务器=>顶级域名服务器=>权威域名服务器)直到找到目标ip地址
发起tcp连接
- 调用socket接口发起tcp建立请求
- tcp三次握手建立连接
- 客户端调用socket.connect()函数,发送包含SYN标志位的数据包给服务端(第一次握手)
- 服务端收到带有SYN标志位的数据包,知道这是要建立连接,于是也组建一个数据包(包含SYN、ACK,ACK用于表示确认接收到了客户端发送的数据包),发送给客户端(第二次握手)
- 客户端组建数据包并设置ACK字段发送给服务端,客户端进入establish状态
- 服务端接收到数据包,确认无误后也进入establish状态,这时连接就建立成功了
- 发起http请求:
- 如果是https请求则还需建立SSL/TSL连接:
在这之后就可以进行愉快的请求啦
- 如果是https请求则还需建立SSL/TSL连接:
- 开始发送请求后就涉及到缓存:
- 首先浏览器查看本地是否有缓存,如果没有则直接向服务器请求数据
- 如果有则查看Cache-control或expires是否过期,如果没过期则直接使用本地数据
- 过期了则向服务器发送请求并携带上if-none-matched或if-modified-since字段,如果服务器认定未过期则返回304,加载本地缓存
- 如果过期了则返回200以及新的数据
拿到html页面
走到这一步,我们要进入浏览器的内核看看了
浏览器是多进程的,分为以下几个进程:
- 浏览器进程:浏览器进程负责控制浏览器标签导航栏,以及和其他进程进行协调工作
- 缓存进程:
- 网络进程:负责发起网络请求
- GPU进程:负责界面渲染
- 插件进程:负责控制网站插件(如flash,不是chrome市场中下载的插件)
- 渲染器进程:渲染每个tab标签内的所有内容(默认情况下每个标签页都会有一个渲染器进程)
- 当你在浏览器地址栏输入内容时,浏览器的UI线程会识别你输入的内容,如果访问的是网址则会启动网络线程进行url解析一个网络请求,否则则会使用浏览器默认的搜索引擎进行搜索
- 检查站点是否为恶意站点
- UI线程启动一个渲染器进程进行渲染页面,通过IPC管道将数据传递给渲染器进程
- 渲染器主线程开始解析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:
- 在http1.0的基础上增加了如delete、options、put等方法
- 引入长连接:一个tcp连接可以服用减少了资源的消耗
- 引入管道机制:一个连接可以同时发送多个请求,但是要求返回的响应也要按照请求的顺序,所以实用性不高
- 增加了协商缓存字段
http2:
- 增加多路复用特性,解决http1.1的对头阻塞问题
- 请求和响应被划分为不同的帧,首部帧和数据帧,通过流标识符来确定当前帧属于哪个请求
- 使用Hpack压缩算法对首部进行了压缩,浏览器和服务器共同保存一张静态只读的表,根据表来判断当前字段对应的意思
- 使用二进制传输帧
- 服务器推送:根据浏览器发送的请求,预判需要的资源,一起返回给浏览器
http3:
- 使用UDP
- 使用QUIC协议将握手阶段和TLS握手整合
- 使用连接id判断是否为同一个连接,避免多次握手
Vue路由模式
hash模式
通过window.onhashchange()监听URL中hash值的变换,通过location.hash获取当前的hash值
- 页面不会刷新,更加流畅
- js中则可以通过
location.herf来改变当前的hash值
history模式
js通过history.pushState方法改变URL值,通过window.onpopstate()事件监听URL的变化