You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何JavaScript文件无法像JSP一样正确识别Servlet路径?

问题描述

我有一个标注了@WebServlet("/UserServlet")的Servlet,在JSP里用action="UserServlet"能正常访问,但单独的JS文件里用fetch('/UserServlet')却不行。相关文件路径:

  • Servlet:src/main/java/com.name.controller/UserServlet
  • JSP:webapp/view/
  • JS文件:webapp/js/

JS里用相对路径请求时,会跳转到localhost:8080/UserServlet,而非预期的localhost:8080/ProjectName/UserServlet,只有写全路径才能正常工作。想知道有没有办法不用全路径,只用Servlet名称就能发起请求?

问题根源

这是因为JSP和JS里的路径解析逻辑不一样:

  • JSP中的action="UserServlet"是相对当前页面的URL路径解析的,比如你的JSP访问地址是http://localhost:8080/ProjectName/user.jsp,浏览器会自动把它解析为http://localhost:8080/ProjectName/UserServlet,刚好匹配Servlet的映射。
  • 而JS文件是从http://localhost:8080/ProjectName/js/xxx.js加载的,JS里的/UserServlet是相对于域名根目录的绝对路径,所以浏览器会直接请求http://localhost:8080/UserServlet,漏掉了项目的上下文路径(也就是/ProjectName)。

解决方案

1. 在JSP中注入上下文路径给JS用

JSP可以通过${pageContext.request.contextPath}获取项目的上下文路径,你可以在JSP页面里定义一个全局变量,然后让JS文件引用这个变量:

在JSP的合适位置(比如<head>里)添加:

<script>
    // 定义全局变量存储上下文路径
    const contextPath = "${pageContext.request.contextPath}";
</script>
<!-- 加载你的JS文件 -->
<script src="${pageContext.request.contextPath}/js/你的JS文件名.js"></script>

然后在JS文件里拼接路径:

fetch(contextPath + '/UserServlet', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: registrationDataJSON
})
.then(response => response.json())
.then(data => {
    if (data.status === 'success') {
        // 处理成功逻辑
    } else {
        alert(data.message);
    }
})
.catch(error => {
    console.error(error);
});

2. 纯JS提取上下文路径

如果不想依赖JSP的变量,也可以用JS从当前页面的URL里自动提取上下文路径:

// 提取当前页面的上下文路径
const getContextPath = () => {
    const pathName = window.location.pathname;
    // 找到第一个/之后的第二个/的位置
    const index = pathName.indexOf('/', 1);
    // 返回上下文路径,没有的话返回空字符串
    return index > 0 ? pathName.substring(0, index) : '';
};

const contextPath = getContextPath();

// 发起请求
fetch(contextPath + '/UserServlet', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: registrationDataJSON
})
// 后续处理逻辑...

这种方法不用改JSP,纯JS就能实现,还能兼容项目部署在根路径的情况。

3. 把JS代码内嵌到JSP里

如果这个JS逻辑只在某个JSP页面使用,直接把JS代码写在JSP里就行,这样可以直接用JSP的上下文路径变量:

<script>
    fetch('${pageContext.request.contextPath}/UserServlet', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: registrationDataJSON
    })
    .then(response => response.json())
    .then(data => {
        // 处理逻辑
    })
    .catch(error => {
        console.error(error);
    });
</script>

这种方法简单直接,但不利于JS代码的复用和维护,适合小范围使用的场景。


内容的提问来源于stack exchange,提问作者ctrlCat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:15:13