遇到vue项目部署到服务器后刷新出现404的问题,因为是第一次遇到,所以去了解了一下vue中的两种路由模式: hash模式、html5中的history模式

hash模式

vue-router默认的是hash模式.
hash模式,是指url尾巴后的#号以及后面的字符.hash也被称为锚点,本身是用来做页面定位的.
hash虽然出现在url中,但不会被包括在http请求中,对后端完全没有影响,因此改变hash值不会重新加载页面.
hash值的变化不会导致浏览器向服务器发出请求,而hash改变会触发hashchange事件(只改变#后面的url片段);hash发生变化url都会被浏览器记录下来,从而可以使用浏览器的前进和后退.

history模式

history模式主要是通过history Api的pushState()replaceState()两个方法来实现的.pushState()可以改变url地址且不会发送请求,replaceState()可以读取历史记录栈,还可以对浏览器记录进行修改
以上两个方法可以修改历史状态,下面三个方法可以切换(定位)历史状态

1
2
3
4
history.go(-2);//后退两次
history.go(2);//前进两次
history.back(); //后退
hsitory.forward(); //前进
history和hash的差异
  • history和hash都是利用浏览器的两种特性实现前端路由,history是利用浏览历史记录栈的API实现,hash是监听location对象hash值变化事件来实现
  • history的url没有’#’号,hash反之
  • history修改的url可以是同域的任意url,hash是同文档的url
  • 相同的url,history会触发添加到浏览器历史记录栈中,hash不会触发。
history和hash的优点和缺点
  • history比hash的url美观(没有’#’号)
  • history修改的url可以是同域的任意url,hash则只能是同文档的url
  • history模式往往需要后端支持,如果后端nginx没有覆盖路由地址,就会返回404,hash因为是同文档的url,即使后端没有覆盖路由地址,也不会返回404
  • hash模式下,如果把url作为参数传后端,那么后端会直接从’#‘号截断,只处理’#’号前的url,因此会存在#后的参数内容丢失的问题,不过这个问题hash模式下也有解决的方法。

history模式下部署项目后刷新出现404

Vue是属于单页应用(single-page application)而SPA是一种网络应用程序或网站的模型,所有用户交互是通过动态重写当前页面,前面我们也看到了,不管我们应用有多少页面,构建物都只会产出一个index.html

现在,我们回头来看一下我们的nginx配置

1
2
3
4
5
6
7
8
server {
listen 80;
server_name www.xxx.com;

location / {
index /data/dist/index.html;
}
}

可以根据 nginx 配置得出,当我们在地址栏输入 www.xxx.com 时,这时会打开我们 dist 目录下的 index.html 文件,然后我们在跳转路由进入到 www.xxx.com/login

关键在这里,当我们在 website.com/login 页执行刷新操作,nginx location 是没有相关配置的,所以就会出现 404 的情况

为什么hash模式下没有问题

1
router hash` 模式我们都知道是用符号#表示的,如  `website.com/#/login`, `hash` 的值为 `#/login

它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对服务端完全没有影响,因此改变 hash 不会重新加载页面

hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 website.com/#/login 只有 website.com 会被包含在请求中 ,因此对于服务端来说,即使没有配置location,也不会返回404错误