用 html 的 base 标签,解决静态资源、请求的相对路径问题

本文讨论了Web应用中静态资源加载时遇到的问题,包括如何正确引用资源文件及解决资源路径解析不一致的问题。通过引入上下文路径变量和使用JSTL库简化资源路径配置,提供了解决方案并介绍了在不同场景下应用此解决方案的方法。
问题描述:

项目的静态资源文件放在 webapp/resources/目录,有一个jsp 存放在 webapp/something/test.jsp,

在jsp里引用js、css等资源文件,用相对路径的写法是
<script type='text/javascript' src='resources/js/jquery-1.7.1.js'></script>


我把应用发布在app目录下。正常的访问路径应该是:http://localhost:8080/app/resources/js/jquery-1.7.1.js.


在请求这个不在应用根目录下的jsp时: http://localhost:8080/app/something/test.jsp,这个js的地址被解析成:

http://localhost:8080/app/something/resources/js/jquery-1.7.1.js,无法加载。

如果加上“/”,用绝对路径的写法:

<script type='text/javascript' src='/resources/js/jquery-1.7.1.js'></script>

js的地址被解析成:

http://localhost:8080/something/resources/js/jquery-1.7.1.js,同样无法加载。


解决办法之一:

这时,我们会在jsp里加上
<script type='text/javascript' src='<%=request.getContextPath()%>/resources/js/jquery-1.7.1.js'></script>

再访问http://localhost:8080/app/resources/js/jquery-1.7.1.js。正常。


还可以用jtsl:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<script type='text/javascript' src=<c:url value="/resources/js/jquery-1.7.1.js"/>></script>

但是,如果用ajax的方式加载一个html(这个html本身引用了一些静态资源),或者在js里调用一些请求,都需要在请求前加上这个contextpath,很烦人,也很麻烦。


优雅的解决办法:

在<head>下,加上:
<head>
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>  
<base href="<%=basePath%>"/>  

然后把所有请求、引用资源的地方,直接使用相对路径即可。
<script type='text/javascript' src='resources/js/jquery-1.7.1.js'></script>


使用Thymeleaf的`computeContextPath`方法修改静态资源请求路径,可按以下步骤操作: ### 1. 重写`StandardLinkBuilder` 需要创建一个类继承自`StandardLinkBuilder`,并重写`computeContextPath`方法,在该方法中返回期望的基础URL。以下是示例代码: ```java import org.thymeleaf.context.IExpressionContext; import org.thymeleaf.exceptions.TemplateProcessingException; import org.thymeleaf.linkbuilder.StandardLinkBuilder; import java.util.Map; public class CustomLinkBuilder extends StandardLinkBuilder { private String baseUrl; public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; } @Override protected String computeContextPath(IExpressionContext context, String base, Map<String, Object> parameters) { if (baseUrl == null) { throw new TemplateProcessingException("baseUrl 不能为空"); } return baseUrl; } } ``` ### 2. 配置Thymeleaf使用自定义的`LinkBuilder` 在Spring Boot项目中,可以通过Java配置类来配置Thymeleaf使用自定义的`LinkBuilder`。示例代码如下: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.thymeleaf.spring5.SpringTemplateEngine; import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring5.view.ThymeleafViewResolver; @Configuration public class ThymeleafConfig { @Bean public SpringTemplateEngine templateEngine(SpringResourceTemplateResolver templateResolver) { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver); // 创建并设置自定义的LinkBuilder CustomLinkBuilder customLinkBuilder = new CustomLinkBuilder(); customLinkBuilder.setBaseUrl("https://your-static-resource-url.com"); templateEngine.setLinkBuilder(customLinkBuilder); return templateEngine; } @Bean public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine) { ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setTemplateEngine(templateEngine); return viewResolver; } } ``` ### 3. 在Thymeleaf模板中使用静态资源 在Thymeleaf模板中,使用Thymeleaf的链接表达式来引用静态资源。示例代码如下: ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Custom Static Resource Path</title> <link rel="stylesheet" th:href="@{/css/style.css}"> </head> <body> <h1>Hello, Thymeleaf!</h1> <script th:src="@{/js/script.js}"></script> </body> </html> ``` 通过以上步骤,`computeContextPath`方法会将静态资源请求路径修改为自定义的基础URL。例如,在上述配置中,`@{/css/style.css}`会被解析为`https://your-static-resource-url.com/css/style.css`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值