前端和后端的相对路径和绝对路径

news2024/9/23 4:48:45

1. 相对路径访问图片

  • test.html 位于 web/a/b/c/ 目录中:

    • 若要访问 static/img/ 文件夹中的图片(假设图片名为 image.png),相对路径应该是:
      <img src="../../../static/img/image.png" alt="Image">
      这里 ../../../ 用于返回到 web 目录,再进入 static/img/
  • view.html 位于 WEB-INF/views/ 目录中:

    • WEB-INF 下的文件不能被直接访问,但假设你使用了一些方式(如通过 Servlet 渲染)来显示它,可以通过以下相对路径引用图片:
      <img src="../../static/img/image.png" alt="Image">
      ../../ 用来从 WEB-INF/views/ 跳出两层,回到 web,然后进入 static/img/
  • index.htmlindix.html 位于 web/ 根目录:

    • 若要访问图片,可以使用相对路径:
      <img src="static/img/image.png" alt="Image">

2. 绝对路径访问图片

无论 HTML 文件在哪个目录,绝对路径始终从 Web 应用的根目录(即 web/)开始。假设你的应用部署在服务器的根路径 /,可以使用以下绝对路径:

<img src="/static/img/image.png" alt="Image">

这种方式确保无论 HTML 文件放置在项目的哪个位置,都能够从根目录开始正确访问 static/img/image.png

总结:

  • 相对路径 是基于当前 HTML 文件的层次位置,决定路径中 ../ 的使用次数。
  • 绝对路径 则更为稳定,直接从应用的根目录开始引用,使用 /static/img/image.png

绝对路径的缺点: 

绝对路径要补充项目的上下文,而项目上下文是可以改变的
1. <base> 标签(不完美的解决办法)
  • <base> 标签允许你定义相对路径的公共前缀,一旦定义,所有相对路径(如图片、CSS、JS 等)都会基于这个前缀进行解析。

  • 在你给出的例子中,<base href="/web03_war_exploded/">/web03_war_exploded/ 作为所有相对路径的基准前缀。
2. 适用场景
  • 相对路径<base> 标签对相对路径有效,会将其转换为基于该前缀的绝对路径。例如,如果有一个相对路径 static/img/logo.png,那么完整路径将变为 /web03_war_exploded/static/img/logo.png
  • 绝对路径<base> 对绝对路径无效。如果你直接使用绝对路径,如 /static/img/logo.png,它会忽略 <base> 定义的前缀。
3. 注意事项
  • <base> 标签必须放置在 <head> 标签内,并且在同一 HTML 文档中只能定义一个 <base> 标签。
  • 如果路径以 ./../ 开头,<base> 标签仍会生效,将相对路径基于指定的前缀。

更简便的方法:

 

所有的HTML访问img的代码如下:

 后端 

1. Servlet 重定向 (sendRedirect)

通过 ServletA 来访问 test.html 文件的流程 

1. 相对路径的使用

  • ServletA 中,通过 resp.sendRedirect("../../../a/b/c/test.html"); 实现重定向。这个路径是相对于当前 ServletA 所在的路径 (/web03_war_exploded/x/y/z/servletA)。
    • ../../../ 表示向上跳三层目录,正好跳到根路径 /web03_war_exploded/,然后进入 a/b/c/test.html,最终构成的完整 URL 是:

      http://localhost:8080/web03_war_exploded/a/b/c/test.html

2. 绝对路径的使用

  • 你可以直接使用绝对路径进行重定向,如:

    resp.sendRedirect("/web03_war_exploded/a/b/c/test.html");

    这种方式避免了相对路径中的复杂跳转,直接从服务器根路径开始访问文件。

  • 绝对路径中需要填写项目上下文路径,但是上下文路径是变换的所以需要用到getContextPath();
  • 通过获取项目上下文路径: 如果项目上下文路径是动态的(如部署在不同的服务器或子路径下),推荐通过 ServletContext 获取上下文路径,确保路径的动态适应性:

    resp.sendRedirect(request.getContextPath() + "/a/b/c/test.html");

    这里的 request.getContextPath() 会动态返回当前项目的上下文路径,避免硬编码路径不一致的问题。

    //绝对路径中,要写项目上下文路径
    //resp.sendRedirect("/web03_war_exploded/a/b/c/test.html");
    // 通过ServletContext对象动态获取项目上下文路径
    //resp.sendRedirect(getServletContext().getContextPath()+"/a/b/c/test.html");
    // 缺省项目上下文路径时,直接以/开头即可
    resp.sendRedirect("/a/b/c/test.html");

总结:

  • 相对路径:相对路径的好处是与当前资源位置相关,但可能会因为层级跳转复杂而不易维护,特别是当文件目录结构较深时,容易出错。

  • 绝对路径:绝对路径较为清晰,但需要指定项目的上下文路径,若项目迁移或部署在不同上下文路径下(如 /web03_war_exploded/ 变为 /app/),可能需要修改路径。通过 getContextPath() 动态获取上下文路径能有效避免这个问题。

2. 请求转发 (RequestDispatcher)

1. 相对路径写法

  • 当前的请求是通过 ServletB 访问的,其 URL 为:

    http://localhost:8080/web03_war_exploded/x/y/z/servletB

  • ServletB 转发到目标页面 test.html 的相对路径为:
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("../../../a/b/c/test.html"); 
    requestDispatcher.forward(req, resp);
@WebServlet("/x/y/z/servletA")
public class ServletA extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
        // 相对路径重定向到test.html
        resp.sendRedirect("../../../a/b/c/test.html");
   }
}
  • 解释相对路径
    • ../../../ 表示向上跳出三个层级,从 /x/y/z/ 跳回到根路径 /web03_war_exploded/,然后再进入 a/b/c/test.html
    • 最终路径为:

      http://localhost:8080/web03_war_exploded/a/b/c/test.html

2. 绝对路径写法

  • 另一种方式是使用绝对路径,不需要依赖项目上下文路径而重定向的绝对路径需要依赖项目上下文路径:
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("/a/b/c/test.html"); 
    requestDispatcher.forward(req, resp);
  • 这里的 /a/b/c/test.html 是绝对路径,直接从服务器的根路径开始解析,无需处理层级跳转的问题。这种写法避免了相对路径复杂的目录跳转问题。
@WebServlet("/x/y/servletB")
public class ServletB extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
        RequestDispatcher requestDispatcher =
req.getRequestDispatcher("../../a/b/c/test.html");
        requestDispatcher.forward(req,resp);
   }
}

3. 总结

  • 相对路径:适用于基于当前资源位置进行跳转,需要根据当前请求的位置进行目录层级的跳转。
  • 绝对路径:从项目的根路径开始定义目标资源路径,推荐使用绝对路径来减少复杂性,特别是当资源路径固定时。
  • 请求转发:不同于重定向,请求转发 不会更改客户端的 URL 地址,操作完全在服务器端进行,浏览器不会察觉 URL 变化。
  • 另一种方式是使用绝对路径,不需要依赖项目上下文路径:
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("/a/b/c/test.html"); 
    requestDispatcher.forward(req, resp);
  • 这里的 /a/b/c/test.html 是绝对路径,直接从服务器的根路径开始解析,无需处理层级跳转的问题。这种写法避免了相对路径复杂的目录跳转问题。

目标资源内相对路径处理

  • 此时需要注意,请求转发是服务器行为,浏览器不知道,地址栏不变化,相当于我们访问test.html 的路径为http://localhost:8080/web03_war_exploded/x/y/servletB
  • 那么此时 test.html资源的所在路径就是http://localhost:8080/web03_war_exploded/x/y/所以 test.html中相对路径要基于该路径编写,如果使用绝对路径则不用考虑;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--
 当前资源路径是     http://localhost:8080/web03_war_exploded/x/y/servletB
        当前资源所在路径是 http://localhost:8080/web03_war_exploded/x/y/
        目标资源路径=所在资源路径+src属性值
 http://localhost:8080/web03_war_exploded/x/y/../../static/img/logo.png
        http://localhost:8080/web03_war_exploded/static/img/logo.png
 得到目标路径正是目标资源的访问路径 
    -->
<img src="../../static/img/logo.png">
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2156566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java笔试面试题AI答之设计模式(3)

文章目录 11. Spring开发中的哪里使用了工厂设计模式 &#xff1f;1. BeanFactory2. 工厂方法模式3. 抽象工厂模式4. 示例说明总结 12. 什么是代理模式 &#xff1f;13. 请列举代理模式的应用场景 &#xff1f;14. 什么是原型模式 &#xff1f;15. 请简述Java中原型模式的使用方…

Mixamo动画使用技巧

1、登录Mixiamo网站 2、下载人物模型 3、找到FBX文件 选中人形骨骼 3、下载动画 4、拖拽FBX 5、注意事项 生成的FBX文件中会包含一个骨骼一个动画 如果人物有骨骼&#xff0c;则不需要&#xff0c;没有需要对应此包中的骨骼&#xff0c;骨骼不可以通用&#xff0c;动画通用 …

百度智能云API调用

植物识别API import base64 import urllib import requestsAPI_KEY "你的图像识别API_KEY" SECRET_KEY "你的图像识别SECRET_KEY"def main():url "https://aip.baidubce.com/rest/2.0/image-classify/v1/plant?access_token" get_access_t…

[spring]应用分层 及 Spring IoCDI

文章目录 一. 应用分层二. Spring IoC获取String中的对象五大 类注解1. Controller (控制器存储)2. Service&#xff08;服务存储&#xff09;3. Repository(仓库存储)4. Conponent(组件存储)5. Configuration(配置存储) 方法注解Bean定义多个对象重命名 三. Spring DI属性注入…

排序-----归并排序(递归版)

核心思想&#xff1a;假设数组前后两部分各自有序&#xff0c;然后各定义两个指针&#xff0c;谁小谁放到新开辟的数组里面&#xff0c;最后把新开辟的数组赋值给原数组就完成了。要使前后两部分有序就采用递归的方式&#xff0c;不断往下划分块&#xff0c;最后一层划分为两个…

springboot实战学习(7)(JWT令牌的组成、JWT令牌的使用与验证)

接着上篇博客的学习。上篇博客是在基本完成用户模块的注册接口的开发以及注册时的参数合法性校验的基础上&#xff0c;基本完成用户模块的登录接口的主逻辑以及提到了问题&#xff1a;"用户未登录&#xff0c;需要通过登录&#xff0c;获取到令牌进行登录认证&#xff0c;…

Unity对象池的高级写法 (Plus优化版)

唐老师关于对物体分类的OOD的写法确实十分好&#xff0c;代码也耦合度也低&#xff0c;但是我有个简单的写法同样能实现一样的效果&#xff0c;所以我就充分发挥了一下主观能动性 相较于基本功能&#xff0c;这一版做出了如下改动 1.限制了对象池最大数量&#xff0c;多出来的…

Pybullet 安装过程

Pybullet 安装过程&#xff08;windows&#xff09; 1. 安装C编译工具2. 安装Pybullet 1. 安装C编译工具 pybullet 需要C编译套件&#xff0c;直接装之前检查下&#xff0c;要不会报缺少某版本MVSC的error&#xff0c;最好的方式是直接下载visual studio&#xff0c;直接按默认…

多无人机通信(多机通信)+配置ssh服务

目录 多机通信 设备 主从机通信设置 配置从机 配置主机 测试 正式启用 MAVROS通信 多机通信 多机通信是实现机器人编队的基础&#xff0c;通过网络搭建通信链路。我们这里用中心节点网络通信&#xff0c;所有数据需有经过中心节点&#xff0c;所以&#xff0c;中心节点…

【有啥问啥】探索累计推理(Cumulative Reasoning, CR)——大型语言模型中的复杂推理新框架

探索累计推理&#xff08;Cumulative Reasoning, CR&#xff09;——大型语言模型中的复杂推理新框架 引言 随着人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;大型语言模型&#xff08;LLMs&#xff09;在自然语言处理上的表现令人瞩目。然而&#xff0c;LLMs在…

实现人体模型可点击

简化需求&#xff1a;实现项目内嵌人体模型&#xff0c;实现点击不同部位弹出部位名称 一&#xff1a;优先3d&#xff0c; 方案&#xff1a;基于three.js&#xff0c;.gltf格式模型&#xff0c;vue3 缺点&#xff1a;合适且免费的3d模型找不到&#xff0c;因为项目对部位有要…

深度学习——D2(数据操作)

N维数组 创建数组 访问元素 一列: [ : , 1 ] 反向累积、正向累积&#xff08;自动求导&#xff09; 梯度 梯度&#xff08;Gradient&#xff09;是微积分中的一个重要概念&#xff0c;主要用于描述一个函数在某个区域内的变化情况。以下是对梯度的详细解释&#xff1a; 一…

树莓派pico上手

0 介绍 不同于作为单板计算机的树莓派5&#xff0c;树莓派 pico 是一款低成本、高性能的微控制器板&#xff0c;具有灵活的数字接口。主要功能包括&#xff1a; 英国树莓派公司设计的 RP2040 微控制器芯片双核 Arm Cortex M0 处理器&#xff0c;弹性的时钟频率高达 133 MHz26…

Qt笔记(十七)cmake编译Qt项目

Qt笔记&#xff08;十七&#xff09;cmake编译Qt项目 1. 文件内容与文件结构1.1.文件目录1.2. CMakeLists.txt内容1.3. main.cpp文件1.4. mouseevent.h1.5. mouseevent.cpp1.6. 生成Visual Studio项目后编译报错1.7. 界面显示中文乱码问题 1. 文件内容与文件结构 1.1.文件目录…

神奇的可变模板参数的应用(C++标准库双向链表 list 中的emplace函数实现)

我们先来看一个可以构造任意对象的函数&#xff1a; /// <summary> /// 可以构造任意对象的函数 /// </summary> /// <typeparam name"MyClass">要转换对象的类型</typeparam> /// <typeparam name"...MyClassConstructorParameterT…

传输层 II(TCP协议——协议的特点、报文段、连接管理)【★★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 一、TCP 协议的特点 TCP 是在不可靠的 IP 层之上实现的可靠的数据传输协议&#xff0c;它主要解决传输的可靠、有序、无丢失和不重复问题。TCP 是 TCP/IP 体系中非…

使用Stream实现事件流

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了Flutter中的异步操作&#xff0c;本章回中将介绍Flutter中的事件流.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在上一章回中介绍了异步操作相关的内容&#xff0c;本章回中将介绍如何把…

施耐德EcoStruxure Machine SCADA Expert(EMSE)与SQL数据库连接(十五)

我习惯使用SQL Server 数据库与EMSE进行连接。 用的是sql 2017 关于数据库软件的安装教程 网上一大把。 1.新建数据库 打开数据库管理工具&#xff0c;新建数据库 2.新建表单 &#xff08;ps:这里先做一个小测试-----目的是验证与EMSE软件的链接是否顺畅。) 添加两个元素进去…

图神经网络的新篇章:通用、强大、可扩展的图变换器

人工智能咨询培训老师叶梓 转载标明出处 图变换器&#xff08;Graph Transformers, GTs&#xff09;因其在处理节点间全局依赖关系方面的能力而受到广泛关注。然而&#xff0c;现有的GTs模型在处理大规模图时面临着计算复杂度高、泛化能力有限等问题。为了解决这些问题&#x…

对比评测5款实用在线翻译工具,包括有道在线翻译

大家好&#xff0c;今天咱们来聊聊在线翻译工具。在这个信息爆炸的时代&#xff0c;语言不再是沟通的障碍&#xff0c;多亏了这些强大的翻译神器。今天&#xff0c;我将带大家比较五款热门的在线翻译工具&#xff0c;究竟谁更胜一筹呢&#xff1f;让我们一探究竟&#xff01; …