前言
路由这概念最开始是在后端出现的,在前后端不分离的时候,由后端来控制路由,服务器接收客户端的请求,解析对应的url路径,并返回对应的页面/资源。简单的说,路由就是根据不同的url地址来展示不同的内容或页面。
现在的网络应用程序越来越多的使用AJAX异步请求完成页面的无缝刷新,虽然Ajax解决了用户交互时体验的痛点,但是多页面之间的跳转一样会有不好的体验,所以便有了spa(single-page application)使用的诞生。而spa应用便是基于前端路由实现的,所以便有了前端路由。
前端路由的原理本质上就是在不刷新浏览器的情况下,请求下修改URL、检测URL的变化,截获URL的地址,通过解析、匹配路由规则从而实现UI的更新。路由的实现通常有两种形式一种是Hash模式,一种是History模式。
vue-router 在实现单页面路由时,提供了两种方式:Hash 模式和 History 模式;vue2是 根据 mode 参数来决定采用哪种方式,默认是 Hash 模式,手动设置为 History 模式 。
hash
模式是一种把前端路由的路径用井号 #
拼接在真实 url
后面的模式。当井号 #
后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 onhashchange
事件。
hash 模式是利用了 window 可以监听 onhashchange 事件来实现的,也就是说 hash 值是用来指导浏览器动作的,对服务器没有影响,HTTP 请求中也不会包括 hash 值,同时每一次改变 hash 值,都会在浏览器的访问历史中增加一个记录,使用“后退”按钮,就可以回到上一个位置。所以,hash 模式 是根据 hash 值来发生改变,根据不同的值,渲染指定DOM位置的不同数据。
哈希值
并且哈希值它不会作为路径的一部分随着 http 请求,发给服务器hash
永远不会提交到 server
端(可以理解为只在前端自生自灭)。window.history 属性指向 History 对象,它表示当前窗口的浏览历史。当发生改变时,只会改变页面的路径,不会刷新页面。 History 对象保存了当前窗口访问过的所有页面网址。通过 history.length 可以得出当前窗口浏览网址的记录。 由于安全原因,浏览器不允许脚本读取这些地址,但是允许在地址之间导航。 浏览器工具栏的“前进”和“后退”按钮,其实就是对 History 对象进行操作。
satbleObject 是一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,都会触发popstate事件,并能在事件中使用该对象。
每当 history 对象出现变化时,就会触发 popstate 事件。 window.addEventListener('popstate', e => {});
在前端性能优化的方式中,最重要的当然是缓存了,使用好了缓存,对项目有很大的帮助。比如我们访问网页时,使用网页后退功能,会发现加载的非常快,体验感很好,这就是缓存的力量。
Web缓存种类: 数据库缓存,CDN缓存,代理服务器缓存,浏览器缓存。
每个浏览器都实现了HTTP缓存,我们通过浏览器使用HTTP协议与服务器交互的时候,浏览器会根据一套与服务器约定的规则进行缓存工作。浏览器的前进/后退,利用的是浏览器的缓存机制。
浏览器缓存其实就是指在本地使用的计算机中开辟一个内存区,同时也开辟一个硬盘区作为数据传输的缓冲区,然后用这个缓冲区来暂时保存用户以前访问过的信息。
浏览器缓存位置一般分为四类: Service Worker–>Memory Cache–>Disk Cache–>Push Cache。
强缓存是当我们访问URL的时候,不会向服务器发送请求,直接从缓存中读取资源,但是会返回200的状态码。
我们第一次进入页面,请求服务器,然后服务器进行应答,浏览器会根据response Header来判断是否对资源进行缓存,如果响应头中expires、pragma或者cache-control字段,代表这是强缓存,浏览器就会把资源缓存在memory cache 或 disk cache中。
第二次请求时,浏览器判断请求参数,如果符合强缓存条件就直接返回状态码200,从本地缓存中拿数据。否则把响应参数存在request header请求头中,看是否符合协商缓存,符合则返回状态码304,不符合则服务器会返回全新资源。
以下是强缓存的字段
是HTTP1.0控制网页缓存的字段,值为一个时间戳,服务器返回该请求结果缓存的到期时间,意思就是,再次发送请求时,如果未超过过期时间,直接使用该缓存,如果过期了则重新请求。
有个缺点,就是它判断是否过期是用本地时间来判断的,本地时间是可以自己修改的。
是HTTP1.1中控制网页缓存的字段,当Cache-Control都存在时,Cache-Control优先级更高,主要取值为:
public:客户端和服务器都可以缓存(所有内容都将被缓存)。
privite:资源只有客户端可以缓存(Cache-Control的默认值)。
no-cache:客户端缓存资源,但是是否缓存需要经过协商缓存来验证。
no-store:不使用缓存(不使用强缓存,也不使用协商缓存)。
max-age:设置缓失效时间。
Cache-Control使用了max-age相对时间,解决了expires的问题。
这个是HTTP1.0中禁用网页缓存的字段,其取值为no-cache,和Cache-Control的no-cache效果一样。 http1.1中可用Cache-Control替换
强缓存会把资源房放到memory cache 和 disk cache中
查找浏览器缓存时会按顺序查找: Service Worker–>Memory Cache–>Disk Cache–>Push Cache。
是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。
内存中的缓存,主要包含的是当前页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。
存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。
在所有浏览器缓存中,Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。绝大部分的缓存都来自 Disk Cache。
link标签上带了prefetch,再次加载会出现。
prefetch是预加载的一种方式,被标记为prefetch的资源,将会被浏览器在空闲时间加载。
Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟左右,同时它也并非严格执行HTTP头中的缓存指令。
协商缓存就是强缓存失效后,浏览器携带缓存标识向服务器发送请求,由服务器根据缓存标识来决定是否使用缓存的过程。
主要有以下两种情况:
304 状态码表示客户端发送携带有缓存标识(GET方法的请求报文中包含If-Math,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任意首部)的请求时,因为服务器端的资源未改变,可直接使用客户端未过期的缓存。304状态码返回时,不包含任何响应的主体部分,304虽然划分到3XX类型状态码中,但是和重定向没有关系
如果发起携带缓存标识资源请求时候服务器的资源已经更新。则返回请求结果,成功的话状态码为200
Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。
If-Modified-Since则是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。服务器收到该请求,发现请求头含有If-Modified-Since字段,则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件。
Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。
If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200。
Etag / If-None-Match优先级高于Last-Modified / If-Modified-Since,同时存在则只有Etag / If-None-Match生效。
目前的项目大多使用的缓存方案:
强缓存不发请求到服务器,所以有时候资源更新了浏览器还不知道,但是协商缓存会发请求到服务器,所以资源是否更新,服务器肯定知道。
大部分web服务器都默认开启协商缓存。
当ctrl+f5强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存。
当f5刷新网页时,跳过强缓存,但是会检查协商缓存。
浏览器地址栏中写入URL,回车 浏览器发现缓存中有这个文件了,不用继续请求了,直接去缓存拿。(最快)
由请求行和HTTP头组成
请求行
包含请求的方法,请求的URI和HTTP版本3个字段组成
http协议得请求方法有:
HTTP请求头
HTTP响应也由四个部分组成,分别是:响应行
、响应头
、空行
、响应体
。
包含响应状态码,原因短语和HTTP协议版本
包括通用信息头、请求头、实体头
状态码 | 含义 |
---|---|
1xx | 指示信息–表示请求已接收,继续处理 |
200 | OK 客户端发过来的数据被正常处理 |
204 | Not Content 正常响应,没有实体 |
206 | Partial Content范围请求,返回部分数据,响应报文中由Content-Range指定实体内容 |
301 | Moved Permanently 永久重定向 |
302 | Found 临时重定向,规范要求方法名不变,但是都会改变 |
303 | See Other 和302类似,但必须用GET方法 |
304 | 304 |
307 | Temporary Redirect 临时重定向,不该改变请求方法 |
400 | Bad Request 请求报文语法错误 |
401 | unauthorized 需要认证 |
403 | Forbidden 服务器拒绝访问对应的资源 |
404 | Not Found 服务器上无法找到资源 |
500 | Internal Server Error 服务器故障 |
503 | Service Unavailable 服务器处于超负载或正在停机维护 |
首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存行为 |
Connection | 链接的管理 |
Date | 报文日期 |
Pragma | 报文指令 |
Trailer | 报文尾部的首部 |
Trasfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器信息 |
Warning | 错误通知 |
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | Accept-Encoding |
Accept-Langulage | 优先的语言 |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户的电子邮箱地址 |
Host | 请求资源所在的服务器 |
If-Match | 比较实体标记 |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记 |
If-Range | 资源未更新时发送实体Byte的范围请求 |
If-Unmodified-Since | 比较资源的更新时间(和If-Modified-Since相反) |
Max-Forwards | 最大传输跳数 |
Proxy-Authorization | 代理服务器需要客户端认证 |
Range | 实体字节范围请求 |
Referer | 请求中的URI的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP客户端程序的信息 |