Spring Boot 1.5.9部署Tomcat 8.5.20新增JSP Ajax请求404求助
兄弟,我一眼就看出你这问题出在哪了——新页面的Ajax请求路径没带上Tomcat部署的应用上下文路径!
先给你捋明白逻辑:当你把war包改成ROOT.war部署时,Tomcat会把这个应用当成默认根应用,上下文路径是空的,所以你写的/api/getData这种绝对路径会直接指向localhost:8080/api/getData,刚好命中你的控制器。但用原项目名部署时,Tomcat会给所有请求加上应用名前缀,也就是localhost:8080/applicationame/xxx,可你的新页面Ajax还是硬编码成/api/getData,相当于请求localhost:8080/api/getData,这地方根本没你的接口,可不就404嘛。
至于旧页面为啥没问题?估计旧页面用的是相对路径(比如api/getData,不带开头的斜杠),或者早就用上了动态获取上下文的方式,自然适配了不同部署场景。
下面给你三个靠谱的解决办法,按需选:
1. 把Ajax改成相对路径
最简单的办法,把Ajax里的请求路径开头的斜杠去掉就行。比如原来写的是:
$.ajax({ url: "/api/user/list", // 带斜杠的绝对路径,非ROOT部署必踩坑 type: "GET", success: function(res) { /* 处理逻辑 */ } });
改成不带斜杠的相对路径:
$.ajax({ url: "api/user/list", // 浏览器会自动基于当前页面URL拼接上下文 type: "GET", success: function(res) { /* 处理逻辑 */ } });
这样浏览器会自动把当前页面的URL前缀(也就是localhost:8080/applicationame/)拼到请求路径前面,刚好命中你的接口。
2. 动态获取应用上下文路径
如果你的Ajax请求路径和当前页面不在同一层级,必须用绝对路径的话,就在JSP里动态拿上下文路径。在页面里先加一段脚本:
<script> // 从JSP内置对象里获取应用上下文路径 var ctxPath = "${pageContext.request.contextPath}"; </script>
然后Ajax请求时把路径拼起来:
$.ajax({ url: ctxPath + "/api/user/list", // 不管怎么部署都能自动适配 type: "GET", success: function(res) { /* 处理逻辑 */ } });
这个方法是最稳妥的,不管你是ROOT部署还是自定义名称部署,都不会出错。
3. 统一开发和生产的上下文路径
要是你不想在页面里改代码,还可以在Spring Boot的配置文件里提前指定上下文路径,让开发环境和生产环境的路径保持一致:
在application.properties里加一行:
server.servlet.context-path=/applicationame
这样你本地开发时,访问路径也是localhost:8080/applicationame/xxx,和Tomcat部署的路径完全一样,调试时就能提前发现路径问题,不用等到部署才踩坑。
最后给你个排查小技巧:遇到这类请求404的问题,直接按F12打开浏览器开发者工具,切换到Network标签,看看报错的Ajax请求的具体URL是什么,一眼就能看出是不是少了应用名称前缀。
内容的提问来源于stack exchange,提问作者Mr code.

