项目部署到子目录,路由跳转却到主域名下?正常能访问一刷新就404?——路由模式的困扰

项目部署到子目录,路由跳转却到主域名下?正常能访问一刷新就404?——路由模式的困扰

今天在做项目部署到一个服务器子目录时,遇到了两个问题,这里做下记录

一、路由模式介绍

这里以Vue Router v4版本为例

在Vue Router v4版本有三种模式,官网已经做了详细介绍

Hash 模式

hash 模式是用 createWebHashHistory() 创建的:

import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    //...
  ],
})

它在内部传递的实际 URL 之前使用了一个哈希字符(#)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。不过,它在 SEO 中确实有不好的影响。如果你担心这个问题,可以使用 HTML5 模式。

Memory 模式

Memory 模式不会假定自己处于浏览器环境,因此不会与 URL 交互也不会自动触发初始导航。这使得它非常适合 Node 环境和 SSR。它是用 createMemoryHistory() 创建的,并且需要你在调用 app.use(router) 之后手动 push 到初始导航

import { createRouter, createMemoryHistory } from 'vue-router'
const router = createRouter({
  history: createMemoryHistory(),
  routes: [
    //...
  ],
})

虽然不推荐,你仍可以在浏览器应用程序中使用此模式,但请注意它不会有历史记录,这意味着你无法后退前进

HTML5 模式(v3版本中称为History模式)

createWebHistory() 创建 HTML5 模式,推荐使用这个模式:

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    //...
  ],
})

当使用这种历史模式时,URL 会看起来很 “正常”,例如 https://example.com/user/id。漂亮!

不过,问题来了。由于我们的应用是一个单页的客户端应用,如果没有适当的服务器配置,用户在浏览器中直接访问 https://example.com/user/id,就会得到一个 404 错误。这就尴尬了。

不用担心:要解决这个问题,你需要做的就是在你的服务器上添加一个简单的回退路由。如果 URL 不匹配任何静态资源,它应提供与你的应用程序中的 index.html 相同的页面。漂亮依旧!

更详细参考官网介绍

二、遇到的问题

1.项目部署到子目录,路由跳转却到主域名下解决方法

如果是history模式,需要加上当前部署的子目录,

createWebHistory()方法可以传入base参数,官网如下介绍:

base:基准路径,它被预置到每个 URL 上。这允许在一个域名子文件夹中托管 SPA,例如将 base 设置为 /sub-folder 使得其托管在 example.com/sub-folder

所以代码如下:

//获取当前路径
let path = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1)
const router = createRouter({
  history: createWebHistory(path),
  routes: [
    //...
  ],
});

!打包配置这里路径也需要注意下

这里我用的是vite

defineConfig中的base配置路径,有三种写法如下

  • 绝对 URL 路径名,例如 /foo/
  • 完整的 URL,例如 https://foo.com/(原始的部分在开发环境中不会被使用)
  • 空字符串或 ./(用于嵌入形式的开发)

举例:

如果你的应用被部署在 https://www.xxxx/admin/,则设置 base可以设为为

'/admin/'
''
'./'

这三种其一即可

2.正常能访问一刷新就404解决方法

这个是因为没后端没进行配置,加载单页应用后路由改变均由浏览器处理,而刷新时将会请求当前的链接,而Nginx无法找到对应的页面

这时候需要在在Nginx配置文件nginx.conf中加入如下配置:

try_files $uri $uri/ /index.html;

这里做下举例:

location ^~/xxxx/ {
      root  /xx
      try_files $uri $uri/ /index.html;
    }

还有另一种方法可以同时解决上述两个问题,比如说就不想操作Nginx配置了,那就是更换称为hash模式

const router = createRouter({
  history: createWebHashHistory(path),
  routes: [
    //...
  ],
});

但是会有一些缺点,如上面介绍,自行选择

更换称为hash模式

const router = createRouter({
  history: createWebHashHistory(path),
  routes: [
    //...
  ],
});

但是会有一些缺点,如上面介绍,自行选择

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时雨.`

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值