前后端完全分离下Vue Router history模式的实现

目录

  • 0 简述vue路由history模式原理
  • 1 404问题
  • 2 二级路由刷新空白问题
  • 结语

前段时间上线了使用vue全家桶搭建的个人博客,访问地址为Civitasv’s blog。采用了前后端完全分离模式,将前端页面部署到GitHub pages页面,后端部分部署至阿里云个人服务器,仅用于提供数据和rest服务接口。之前的是采用hash模式,并无问题,但最近感觉很多#不太美观,且不利于SEO,因此考虑将其改变为history模式,遇到了一些问题,特此记录分享。

0 简述vue路由history模式原理

首先,要理解为了构建SPA应用,需要引入vue前端路由系统,其目的在于改变视图不向服务器发送请求,也就是说,向服务器发送页面请求事实上只有最开始的一次,其余的页面均依赖前端路由动态改变引入的资源文件实现。

在实现上述功能时,vue路由history模式利用了H5新增的pushState()replaceState()接口方法,它们分别可以添加和修改历史记录条目。这些方法通常与window.onpopstate 配合使用。假设在http://starss.me上中执行history.pushState(null, null, "home"),浏览器地址会变为http://starss.me/home/,但页面不会刷新,也即不会向服务器发送请求,接着vue router就对该url进行处理,实现无刷新页面变化。

1 404问题

vue官方文档和很多博客均提到history模式下应该提供后台支持.

当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!

不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。

–HTML history模式

首先解释下为什么会出现404,如果在http://starss.me/下存在你的主页即index.html,假如在hash模式下手动输入/刷新了这样一个url链接:

http://starss.me/#/home

则在请求服务器时,会自动去掉#之后的内容,因此服务器会去http://starss.me下寻找index.html,成功后返回页面,改变路由后,通过vue路由配置找到对应的资源即可。但如果我们将其改变为history模式之后,再次手动输入/刷新下面链接:

http://starss.me/home

这样服务器显然会去http://starss.me/home下寻找主页资源,自然不可能找到,因此一定会出现404错误了。

这也即是官网中说到:“要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面”的原因了。这个目的就是在无法匹配资源时,手动配置返回一个应当返回的资源,这个资源也就是我们的主页了,接着vue router就会解析出路由地址,然后根据自己的配置信息找到对应的资源了。

同样的原因,在使用GitHub page时,如果index.html只存在于根目录中,手动输入/刷新访问上面的url也会报404错误,结合其原理,我想到的解决的思路有两个:

  1. GitHub page在404时会访问404.html页面,因此只需要将index.html备份一份,命名为404.html即可,放置在根目录即可,这样控制台仍然会报404错误,但可以正常显示;
  2. 对于url : http://starss.me/home,我们还可以新建一个home文件夹,将index.html复制一份至该文件夹,这样刷新也当然可以访问到它,而且控制台也并不会报404错误。

我的建议是:

  • 如果路由很少,可以按照第二种方式,对每一个路由均新建一个文件夹,然后复制一份index.html,此时也不需要单独配置404页面,GitHub page会给提供(当然也可以配置);

  • 如果路由很多,最好还是按照第一种方式,而且注意这种方式下404.html会被占用,需要单独配置404页面,方法是在路由匹配最下部添加一条即可:

      {
        path: '*',    // 此处需特别注意至于最底部
        name: '404',
        component: () => import('../views/common/404'),
        meta: { title: '404 | Civitasv\'s blog' },
      }
    

按照我的理解,第一种方式其实和前后端不分离模式解决方法思想一致,只是提供一个无法匹配任何已有资源时的候选资源罢了。而第二种可以看作是纯前端的解决方式,可以根据项目实际情况选择使用。

2 二级路由刷新空白问题

这个是路径的原因,只需要在vue.config.js文件中配置publicPath: "/",即可,事实上,这只是个绝对路径和相对路径的问题罢了。

结语

GitHub page链接:https://github.com/Civitasv/civitasv.github.io

博客源码链接:https://github.com/Civitasv/blog

如果仍不清楚,可以留言给我,我看到就会回复

如果喜欢这篇文章,希望你点个赞

and如果有兴趣的话,关注公众号:林木菌,和我一起成长pa~~

你可能感兴趣的:(前端,Vue,vue,js,路由,history,GitHub,pages)