vue history模式刷新页面进入404解决方案
为什么会出现404
nginx.conf:
server {
listen 80;
server_name example.com;
location / {
root /app/dist;
index index.html index.htm;
}
}
Vue是单页应用(SPA),dist下只有一个 index.html 文件及一些静态资源。index.html作为入口文件,其它的路由都是通过JS来进行跳转。
根据 nginx 配置,当在地址栏输入example.com 时,会打开/app/dist目录下的 index.html 文件,然后通过next({ name: "login" });或者this.$router.push({ name: "login" });可以跳转路由进入到example.com/login
但是当我们在example.com/login 页执行刷新操作时,nginx location 是没有相关配置的,所以就会出现 404 的情况。
解决方案
将location修改成如下所示就可以了:
location / {
root /app/dist;
try_files $uri $uri/ /index.html;
}
为什么hash模式下没有问题
router hash 模式用符号#表示的,如 example.com/#/login, hash 的值为 #/login
它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对服务端完全没有影响,因此改变 hash 不会重新加载页面
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如example.com/#/login 只有example.com 会被包含在请求中 ,因此对于服务端来说,即使没有配置location,也不会返回404错误。
如何切换history模式
在router.js中配置
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
// 切换路由后滚动条置顶
scrollBehavior() {
return {
x: 0,
y: 0
}
}
})
export default router
在vue.config.js中加上如下配置
module.exports = {
publicPath: '/', //这个必须,引入静态资源需要从根路径引入,否则会找不到静态资源
devServer: {
// history模式下的url会请求到服务器端,但是服务器端并没有这一个资源文件,就会返回404,所以需要配置这一项
historyApiFallback: {
index: '/index.html' //与output的publicPath
},
},
}
补充:单页应用(single-page application)
单页应用(single-page application),缩写SPA 是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,而非传统的从服务器重新加载整个新页面。这种方法避免了页面之间切换打断用户体验,使应用程序更像一个桌面应用程序。在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面。尽管可以用位置散列或HTML5历史API来提供应用程序中单独逻辑页面的感知和导航能力,但页面在过程中的任何时间点都不会重新加载,也不会将控制转移到其他页面
优点:
- 无刷新体验,由于路由分发直接在浏览器端完成,页面是不刷新,对用户的响应非常及时,因此提升了用户体验
- 完全的前端组件化,前端开发不再以页面为单位,更多地采用组件化的思想,代码结构和组织方式更加规范化,便于修改和调整
缺点:
- 首屏较长,要在一个页面上为用户提供产品的所有功能,在这个页面加载的时候,首先要加载大量的静态资源,这个加载时间相对比较长
- 不利于 SEO,单页页面,数据在前端渲染,就意味着没有 SEO,或者需要使用变通的方案