Spring Boot结合JavaScript如何实现带尾部斜杠的URL重定向?
URL尾部自动追加正斜杠重定向实现方案
原有方案失效原因
- 仅将接口映射路径修改为
/about/时,Spring MVC默认匹配规则下,访问/about会直接返回404,写在页面里的JS脚本根本不会加载执行。 - 前端JS重定向逻辑存在天然缺陷:只能处理页面成功加载的GET请求场景,原接口支持的POST请求提交到无斜杠路径时,JS跳转只会发起GET请求,会直接丢失请求参数、导致请求方法失效。
- 前端跳转还会出现页面先加载再跳转的闪烁问题,用户体验差。
推荐实现方案
优先选择后端全局配置实现,一次配置所有路径生效,兼容GET/POST所有请求方法。
1. 配置Spring MVC路径匹配规则
新建Web配置类,开启尾斜杠匹配支持:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.util.UrlPathHelper; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper pathHelper = new UrlPathHelper(); configurer.setUrlPathHelper(pathHelper); // 开启尾斜杠匹配,让无斜杠请求能先进入拦截处理逻辑,不会直接404 configurer.setUseTrailingSlashMatch(true); } }
如果是Spring Boot 3.x版本,还需要在application.properties中补充配置:
spring.mvc.pathmatch.use-trailing-slash-match=true
2. 编写全局拦截器实现重定向
拦截所有请求,判断路径无尾斜杠时自动301重定向到带斜杠地址,同时保留原查询参数:
import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TrailingSlashRedirectInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestUri = request.getRequestURI(); String contextPath = request.getContextPath(); // 跳过根路径、已带尾斜杠路径、带后缀的静态资源(js/css/图片等) if (requestUri.endsWith("/") || requestUri.contains(".") || requestUri.equals(contextPath)) { return true; } // 拼接重定向地址,保留原始查询参数 String targetUrl = requestUri + "/"; if (request.getQueryString() != null) { targetUrl += "?" + request.getQueryString(); } // 301永久重定向,对SEO友好,需要临时重定向可替换为SC_MOVED_TEMPORARILY(302) response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); response.sendRedirect(targetUrl); return false; } }
3. 注册拦截器
回到之前的WebMvcConfig类,重写addInterceptors方法注册拦截器,排除静态资源路径:
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new TrailingSlashRedirectInterceptor()) .addPathPatterns("/**") // 根据自己项目的静态资源路径调整排除规则 .excludePathPatterns("/static/**", "/assets/**", "/favicon.ico"); }
单接口快速兼容方案
如果不想做全局配置,可直接修改单个接口的映射路径,同时处理重定向逻辑:
// 同时映射带斜杠和不带斜杠两个路径 @RequestMapping(value= {"/about", "/about/"},method= {RequestMethod.GET,RequestMethod.POST}) public ModelAndView about(HttpServletRequest request, HttpSession session) { String requestUri = request.getRequestURI(); // 无尾斜杠时直接重定向 if (!requestUri.endsWith("/")) { String queryStr = request.getQueryString() == null ? "" : "?" + request.getQueryString(); return new ModelAndView("redirect:" + requestUri + "/" + queryStr); } ModelAndView modelAndView = new ModelAndView("/about/"); return modelAndView; }
注意事项
- 配置完成后删除之前写的前端JS重定向代码,后端重定向在请求接入层就完成处理,不会有页面闪烁问题。
- 301重定向会被浏览器缓存,测试时如果遇到缓存问题可先清浏览器缓存,或者临时改用302调试。
内容的提问来源于stack exchange,提问作者Rakhi
相关产品推荐
相关产品推荐

