是否可以为 Vue Router 的历史模式配置 Spring Cloud Gateway 的重写规则?

Is it possible to configure Spring Cloud Gateway with a Rewrite rule for Vue Router's history mode?

我正在使用 Spring 云网关作为 API 网关,同时也作为托管 Vue.js SPA 静态文件 (html/js/css) 的网络服务器。

Preclaimer:由于组织限制,我无法更改此(错误的)架构。

目前,我正在使用默认的 Vue Router hash 模式,这意味着 Vue 应用程序的客户端路由是通过 URL 哈希完成的

http://hostname/#/route?parameter1=true

因为Spring云网关也作为认证网关,它重定向到OAuth2/OpenID SSO服务器,这样,URL散列的路由信息​​是重定向后丢弃。

我正在尝试通过切换到 Vue Router's history mode 来更改此行为,这将启用 URL 之类的

http://hostname/route?parameter1=true

因此,路由信息将在 SSO 重定向中“幸存”。

为此,Vue Router 文档包括 some examples for additional Webserver configuration (like mod_rewrite for Apache etc.)

遗憾的是,没有针对我的特殊情况的示例;-)

我扫描了 Spring Cloud Gateway 的文档,但没有找到与此案例匹配的内容。

简而言之:

是否可以配置 Spring Cloud Gateway 以匹配 Vue Router 的历史模式要求?

您可以从 Spring 引导端修复它。我的意思是,你可以:

  1. 按照文档中的说明启用 Vue Router 历史记录模式 here
  2. 像这样构建一个 Spring 引导转发控制器:
        @RequestMapping(value = "{_:^(?!index\.html|api).$}")
        public String redirectApi() {
            LOG.info("URL entered directly into the Browser, so we need to redirect...");
            return "forward:/";
        }

它基本上将所有路由转发到前端,除了://index.html/api/api/**.

Here你可以找到更详细的例子。

可以通过自定义来完成RouterFunction:

@Bean
public RouterFunction<ServerResponse> vueHistoryModeCatchAllRoute(
        @Value("classpath:/static/index.html") final Resource indexHtml) {
    HandlerFunction<ServerResponse> serveIndexHtmlFunction = request -> ok().contentType(MediaType.TEXT_HTML)
            .bodyValue(indexHtml);
    String firstApiSegmentExcludes = "api|actuator|js|img|css|fonts|favicon\.ico";
    return route(GET("/{path:^(?!" + firstApiSegmentExcludes + ").*}"), serveIndexHtmlFunction)
            .and(route(GET("/{path:^(?!" + firstApiSegmentExcludes + ").*}/**"),
                    serveIndexHtmlFunction));
}

这将为所有请求提供 index.html(包含 Vue.js 应用程序),这些请求与排除的路径之一 (firstApiSegmentExcludes) 不匹配。