bal*_*teo 4 spring-webflux angular-router
我正在尝试实现这里描述的技术:使用带有 webflux 的servlet 的 html5 模式。
简而言之,用户需要能够从浏览器刷新页面,而不会404从 Spring Boot重定向到白标签页面。
上面的教程依赖于使用 servletforward:机制的技术:
@Controller
public class ForwardController {
@RequestMapping(value = "/**/{[path:[^\\.]*}")
public String redirect() {
// Forward to home page so that route is preserved.
return "forward:/";
}
}
Run Code Online (Sandbox Code Playgroud)
但是我使用webflux而不是servlets。这是我尝试使用的方法WebFilter:
@Component
public class SpaWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
if (!path.startsWith("/api") && path.matches("[^\\\\.]*")) {
return chain.filter(
exchange.mutate().request(exchange.getRequest().mutate().path("/").build()
).build());
}
return chain.filter(exchange);
}
}
Run Code Online (Sandbox Code Playgroud)
当用户刷新页面时,这会导致404.
编辑:让我更详细地描述这个问题:
在浏览器中加载 SPA 后,用户可以使用角度路由链接进行导航。说从 http://localhost:8080/到http://localhost:8080/user-list(这里/user-list是一个角度路线。这个导航与后端没有交互。
现在,当用户 - 仍在/user-list路由上 - 选择刷新浏览器页面时,Spring 将尝试解析/user-list后端处理程序/路由器函数的路径,这将导致 Spring Boot 提供的 404 白标签错误页面。
我想要实现的是,http://localhost:8080/user-list当用户刷新浏览器页面时,页面仍然显示给用户。
编辑 2:请注意,索引页 ( http://localhost:8080/)上不会出现此刷新问题,因为我已实施此过滤器:
@Component
public class IndexWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
if (exchange.getRequest().getURI().getPath().equals("/")) {
return chain.filter(
exchange.mutate().request(exchange.getRequest().mutate().path("/index.html").build()
).build()
);
}
return chain.filter(exchange);
}
}
Run Code Online (Sandbox Code Playgroud)
为我的每个 Angular 路由实现一个这样的过滤器显然是不可行的......
编辑 3:另请注意,出现此问题是因为前端作为后端类路径上的 jar 使用以下配置:
@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/");
registry.addResourceHandler("/").addResourceLocations("classpath:/index.html");
}
}
Run Code Online (Sandbox Code Playgroud)
换句话说,我既不使用前端代理也不使用反向代理(例如 nginx)
我已经找到了解决我的问题的方法。我弄错的是“转发”到的网址的值。
通过使用/index.html代替/,应用程序按预期运行。
@Component
public class SpaWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
if (!path.startsWith("/api") && path.matches("[^\\\\.]*")) {
return chain.filter(
exchange.mutate().request(exchange.getRequest().mutate().path("/index.html").build()
).build());
}
return chain.filter(exchange);
}
}
Run Code Online (Sandbox Code Playgroud)
同样可以通过 NGINX 实现,如下所示:
location / {
try_files $uri $uri/ /index.html;
}
Run Code Online (Sandbox Code Playgroud)
这假设角度路由不能包含任何点并且不能以/api前缀开头。
| 归档时间: |
|
| 查看次数: |
701 次 |
| 最近记录: |