文章目录
- 前言
- 一、为什么要有前端路由?
- 二、前端路由模式
- 1.hash
- 优点
- 缺点
- 2.history
- 优点
- 缺点
- 三、为什么history会404呢?
- 1.原因
- 2.解决方式
- 总结
前言
不知道大家有没有遇到过一种情况,当自己的vue部署在服务器上时,一切都如想象办运转,然后脑袋duang的一下,突然想去刷新,然后网页就duang的一下,白屏了。
不出意外的话,我猜你用的一定是history的路由模式。
没错,这就是history中的一个问题,接下来让我们带着问题一起探索一下前端路由吧!
一、为什么要有前端路由?
对于 Vue 这类渐进式前端开发框架,为了构建 SPA(单页面应用),需要引入前端路由系统,这也就是 Vue-Router 存在的意义。前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求。
二、前端路由模式
为了达到这一目的,浏览器当前提供了以下两种支持:
hash模式和history 模式,接下来让我们一起来分析一下这两种路由模式吧!
1.hash
hash 模式是一种把前端路由的路径用井号 # 拼接在真实 URL 后面的模式。当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 hashchange 事件。
即地址栏 URL 中的 # 符号。比如这个 URL:http://www.test.com/#/test,hash 的值为 #/test。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求 中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
优点
- 由于在hash模式下,仅hash符号之前的内容会被包含在请求中,即使在后端没有做到全覆盖,也不会造成影响而返回404错误
- 兼容性较好,支持IE8
缺点
- 路径带有#字符,比较丑陋,在现在这个追求用户体验的时代,大家都希望把用户体验提升到最佳。
- 只能前进和后退一级路由。
2.history
history是利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求。
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。所以只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
优点
- 路径优美,不会携带#字符。
- 前进后退操作可多级,例如 history.go(-2) 可回退两次。
缺点
- 由于使用了H5的方法,所以兼容性较差,只支持IE10及以上。
- 前端的 URL 必须和实际向后端发起请求的 URL 一致,否则需要服务端支持。
三、为什么history会404呢?
前面已经大致介绍了两种路由,那么为什么history路由在线上环境后刷新会404呢?
1.原因
SPA 虽然在浏览器里游刃有余,但真要通过 URL 向后端发起 HTTP 请求时,两者的差异就来了。尤其在用户手动输入 URL 后回车,或者刷新(重启)浏览器的时候。
- 在 hash 模式下,仅 hash 符号(也就是#)之前的内容会被包含在请求中,如 http://www.test.com ,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
- history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.test.com/user/id。如果后端缺少对 /user/id 的路由处理,将返回 404 错误
2.解决方式
那么如果我就是嫌#太丑,就是想用history该怎么办呢?别慌,这就来!
我们可以在Nginx里面配置的 location / 中增加一行
try_files $uri /index.html;
$uri表示的是与当前路由匹配的内容,举个例子:
当前路由为http://www.test.com,此时$uri=http://www.test.com;
总结
通过对两种路由的了解,我们在解决了404问题的同时,也懂得了两种路由的实现原理,也对两种路由的使用方法有了更深层次的理解。