ajax请求中url写法的问题(相对路径和绝对路径)

在开发中,遇到Ajax请求URL路径问题。当在JSP页面中,URL写成'login'时能成功访问,而'/system/login'却不行。分析发现,'login'作为相对路径,相对于当前页面进行解析,而'/system/login'被当作从服务器根路径开始的路径,导致请求失败。理解绝对路径和相对路径的区别对于正确构建Ajax请求至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.开发中遇到的问题

在一个jsp页面中,一个jsp页面中ajax请求中url是这样写的
在这里插入图片描述
很明显我是想要向controller中发送请求,我的controller中的RequestMapping是这写的
在这里插入图片描述
在这里插入图片描述
我之前发送ajax请求中的url都是写成/system/login这样,但是这里我不太清楚为什么直接写成login可以访问,但是写成/system/login却不能访问

二.问题分析

在查看浏览器检查中,发现没有改动url即写成’login’时,是可以正确访问的到的。在这里插入图片描述
当我改为/system/login时,无法找到正确路径
在这里插入图片描述
看这里可以看到这个路径把项目名丢了,于是想到是相对路径和绝对路径的问题

三.ajax请求中url中的相对路径和绝对路径

  1. 绝对路径
    即包含完全请求路径,即请求头,主机地址,端口,项目名等都有,在这个例子中,绝对路径为http://localhost:8080/HotelSSM/system/login

  2. 相对路径
    url中的相对路径分为两种:

    1. 有’/‘符号,在这个例子中,/system/login即为这一种,开头的’/'是指根路径,其相对的是服务器的根路径,即为http://localhost:8080。所以当我填写为/system/login时,访问的路径会变为http://localhost:8080/system/login
      在这里插入图片描述
    2. 无’/'符号,在这个例子中,'login’即为这一种,其相对的是我这个jsp页面的地址,我这个jsp页面的地址为http://localhost:8080/HotelSSM/system/login,当我发送ajax请求中,因为其没有经过视图解析器,又因为相对路径的作用,所以会找controller中的system/login的post方法,所以会正确访问到这个方法。
<think>我们正在讨论的是在JavaWeb应用中如何正确编路径以避免404错误的问题。根据之前的讨论引用内容,我们可以总结如下:1.在Servlet中,我们使用`@WebServlet`注解来定义Servlet的访问路径,例如`@WebServlet("/loginServlet")`。2.在JSP或HTML表单中,我们通过action属性来指定提交的Servlet路径。3.在重定向(sendRedirect)或转发(forward)时,也需要正确设置路径。关键点在于:路径写法是否应该使用动态获取上下文路径(即`${pageContext.request.contextPath}`)的方式?根据引用[3]:给服务器使用的路径(如转发)不需要加虚拟目录(即上下文路径),因为转发是在同一个项目内跳转。但是,给客户端使用的路径(如重定向、表单提交、超链接等)需要加上虚拟目录(即上下文路径),因为客户端请求是从根路径开始。因此,我们需要区分不同的情况:###1.客户端路径(需要加上下文路径)-表单提交(formaction)-超链接(ahref)-重定向(response.sendRedirect)-注意:重定向是客户端行为,所以需要加上下文路径例如:```jsp<!--表单--><formaction="${pageContext.request.contextPath}/loginServlet"method="post">``````jsp<!--超链接--><ahref="${pageContext.request.contextPath}/loginServlet">登录</a>``````java//重定向resp.sendRedirect(req.getContextPath()+"/loginServlet");```###2.服务器端路径(不需要加上下文路径)-转发(RequestDispatcher的forward)-包含(include)例如:```java//转发RequestDispatcherdispatcher=req.getRequestDispatcher("/loginServlet");dispatcher.forward(req,resp);```###3.Servlet注解中的路径在`@WebServlet`注解中,我们路径是相对于上下文路径的,所以直接`/loginServlet`即可,不需要上下文路径。例如:```java@WebServlet("/loginServlet")publicclassLoginServletextendsHttpServlet{...}```###总结:-**不是所有跳转都需要使用动态路径写法**,但所有**客户端发起的请求路径**(包括重定向)都需要包含上下文路径(即项目名)。-在JSP页面中,使用`${pageContext.request.contextPath}`来动态获取上下文路径,避免硬编码。-在Servlet中进行重定向时,使用`request.getContextPath()`来获取上下文路径,然后拼接Servlet路径。-服务器端跳转(转发)不需要上下文路径,因为是在同一个应用内。###示例修正:####重定向示例(引用[2]中的代码需要修正):引用[2]中的重定向代码:```javaresp.sendRedirect("servletB");```如果应用部署在上下文路径`/myapp`下,那么以上重定向会生成路径`http://localhost:8080/servletB`,这会导致404错误,因为正确的路径应该是`http://localhost:8080/myapp/servletB`。修正为:```javaresp.sendRedirect(req.getContextPath()+"/servletB");```####转发示例(引用[3]):转发不需要加上下文路径,所以直接:```javaRequestDispatcherdispatcher=req.getRequestDispatcher("/servletB");dispatcher.forward(req,resp);```###结论:为了避免404错误,我们需要:1.在客户端路径(表单、超链接、重定向)中动态添加上下文路径。2.在服务器端路径(转发)中不添加上下文路径。3.在Servlet注解中,只相对于上下文路径路径。这样,无论项目部署在什么上下文路径下(如根路径`/`或非根路径`/myapp`),路径都能正确解析。###补充:如何动态获取上下文路径?-在JSP中:`${pageContext.request.contextPath}`-在Servlet中:`request.getContextPath()`通过以上方法,可以确保路径的正确性,避免404错误。§§相关问题§§1.如何将JavaWeb项目的访问路径从`http://ip:8080/app`改为根路径`http://ip:8080/`?2.云服务器部署Tomcat后,如何配置HTTPS访问?3.除了404错误,JavaWeb项目部署到云服务器还有哪些常见问题及解决方案?</think>### Servlet 路径跳转中动态路径的使用原则 在 Java Web 开发中,**动态路径写法(`${pageContext.request.contextPath}`)并不是所有场景都需要**,但它是避免 404 错误的关键技术。以下是详细分析: #### ✅ 必须使用动态路径的场景 1. **客户端跳转(浏览器端)**: - 表单提交:`<form action="${pageContext.request.contextPath}/loginServlet">` - 超链接:`<a href="${pageContext.request.contextPath}/get">` - 重定向:`resp.sendRedirect(request.getContextPath() + "/servletB")` [^2] - 前端 AJAX 请求:`url: '${pageContext...}/api'` 2. **跨模块资源引用**: - CSS/JS 文件:`<link href="${pageContext...}/css/style.css">` - 图片资源:`<img src="${pageContext...}/images/logo.png">` #### ⚠️ 不需要动态路径的场景 1. **服务器端跳转(转发)**: ```java // 转发到同一应用内的资源 request.getRequestDispatcher("/WEB-INF/home.jsp").forward(request, response); [^3] ``` - 原因:转发是服务器内部操作,自动包含上下文路径 2. **Servlet 注解定义**: ```java @WebServlet("/get") // 直接路径,不需要上下文 [^1] public class TestServlet extends HttpServlet {...} ``` 3. **WEB-INF 目录访问**: - 安全目录内的资源通过转发访问,无需完整路径 #### 动态路径技术对比表 | 场景 | 是否需要动态路径 | 正确示例 | 错误示例 | |---------------------|------------------|---------------------------------------------|-------------------------| | 表单提交(action) | ✅ 必需 | `${pageContext...}/login` | `action="login"` | | 重定向(sendRedirect)| ✅ 必需 | `resp.sendRedirect(req.getContextPath()+"/b")` | `resp.sendRedirect("b")` | | 请求转发(forward) | ❌ 不需要 | `req.getRequestDispatcher("/result.jsp")` | 添加上下文路径 | | Servlet注解定义 | ❌ 不需要 | `@WebServlet("/api")` | 包含项目名 | | WEB-INF资源访问 | ❌ 不需要 | 通过转发访问 | 直接URL引用 | #### 最佳实践建议 1. **统一路径处理策略**: ```jsp <%-- 在JSP顶部设置路径变量 --%> <c:set var="ctx" value="${pageContext.request.contextPath}"/> <%-- 所有客户端路径使用该变量 --%> <form action="${ctx}/login"> <a href="${ctx}/profile"> ``` 2. **Servlet 中的路径处理**: ```java // 重定向必须包含上下文路径 protected void doPost(...) { String contextPath = request.getContextPath(); response.sendRedirect(contextPath + "/success.jsp"); } ``` 3. **避免硬编码路径**: - 永远不要在代码中死类似`"/myProject/login"`的路径 - 测试时使用`request.getContextPath()`输出当前上下文路径 > **核心原则**:任何需要**浏览器重新发起请求**的操作都必须包含完整上下文路径[^1][^2],而**服务器内部转发**则使用相对路径即可[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值