Vue.JS & Spring 引导 - 在 404 上重定向到主页

Vue.JS & Spring Boot - Redirect to homepage on 404

我正在通过 docker 容器构建一个 Vue.JS 和 Spring 启动应用程序,我是 运行。 Vue 的 dist 文件夹被复制到 resources/public 路径并通过 Spring 引导服务提供。

我已经使用 vue 路由器设置了路由,但是所有这些路由 return 404 - Not found 当直接输入浏览器时(但通过 Vue 应用程序访问时工作正常)。

vue 路由器:

export default new Router({
  mode: 'history',
  routes: [{
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/result',
      name: 'result',
      component: Result,
      props: true
    },
    {
      path: '/result/:userid',
      name: 'autoResult',
      component: Result,
      props: true
    }
  ]
})

我需要 /result/userid 而不是 return 404 - 相反它应该获取用户 ID 并呈现结果页面。这样可以上班吗?

我想做的另一件事是将 映射到任何 api / vue 页面的所有 404 页面重定向到 return 到首页。我已经尝试使用 spring 启动 implements ErrorController 但我无法使重定向工作。

编辑:

我尝试添加以下控制器建议:

@ControllerAdvice
public class WebConfig {

    @ExceptionHandler(NoHandlerFoundException.class)
    public String renderDefaultPage(NoHandlerFoundException e) {
        return "classpath:public/index.html";
    }

}

以及以下属性:

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:public/static/

但是当我现在尝试访问首页(或任何其他 URL)时,我得到了 WhosebugException 并且服务器开始执行无限循环说:

2019-03-05 13:26:24.298  WARN 22044 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound             : No mapping for GET /classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/index.html

你的情况是 Spring 启动正在接受请求,并且因为没有任何东西映射到 URL 给你一个 404。你想要发生的是允许您的 Vue.js 应用程序处理未映射的 URL(即,将任何未映射的 URL 重定向到您的 index.html)。

您需要做的第一件事是将此添加到路由器的路由配置中:

export default new Router({
    mode: 'history',
    routes: [{
        path: '/',
        name: 'home',
        component: Home
    },
    {
        path: '/result',
        name: 'result',
        component: Result,
        props: true
    },
    {
        path: '/result/:userid',
        name: 'autoResult',
        component: Result,
        props: true
    },
    {
        path: '*',
        component: NotFound
    }
  ]
})

这里我们添加了一个额外的路由作为渲染组件的最后一个路径(因为路由是按顺序匹配的)。

之后,您需要让 Spring 引导将每个不匹配的请求重定向到 index.html,为了做到这一点,您希望 spring 在发现并抛出异常时抛出异常未映射的路由和异常处理程序中的重定向到您的 index.html.

首先,将此行添加到您的 application.properties:

spring.mvc.throw-exception-if-no-handler-found=true

并添加一个ControllerAdvice来处理抛出的Exception,像这样:

//In some controller or inside a @ControllerAdvice annotated class
@ExceptionHandler(NoHandlerFoundException.class)
String noHandlerFound(NoHandlerFoundException ex){
    return "classpath:index.html";
}

使用以下代码解决:

@Controller
public class RoutesController implements ErrorController {
    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public String error() {
        return "forward:/";
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

不幸的是 none 以上答案对我有用,幸运的是我在另一个线程中找到了这个答案:

它简单而简短,对我的用例很有帮助,它可能与原始问题略有不同,但我认为它非常相似。对于从 spring 引导后端寻找服务 vuejs SPA 的人来说可能有用。