PAYATHON 2026

Spring MVC/Tiles 弹窗页面为什么没有加载 header.jsp 中的 JS 和 CSS?

数据小陈

结论

在 tiles.xml 中声明 header 属性,不会自动将 header.jsp 插入页面。布局模板还需要通过 <tiles:insertAttribute name="header" /> 输出该属性,弹窗请求也要经过这个 Tiles 布局渲染。

目前没有提供 popupTemplate.jsp、Controller 和视图解析器配置,还不能确定唯一原因。针对“Network 中没有这些资源请求”的现象,建议先检查弹窗返回的 HTML 是否包含资源标签,再检查资源 URL。

1. 检查 popupTemplate.jsp 是否插入了 header

现有配置中,弹窗 definition 继承了 popBase:

<definition name="popBase" template="/WEB-INF/views/template/popupTemplate.jsp">
    <put-attribute name="header" value="/WEB-INF/views/common/header.jsp" />
</definition>

<definition name="svManager/registPj/svProjectList" extends="popBase">
    <put-attribute name="body" value="/WEB-INF/views/svManager/registPj/svProjectList.jsp" />
</definition>

这为布局提供了 header 和 body 两个属性。popupTemplate.jsp 需要明确使用这些属性,例如:

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<!DOCTYPE html>
<html>
<head>
    <tiles:insertAttribute name="header" />
    <title>弹窗</title>
</head>
<body>
    <tiles:insertAttribute name="body" />
</body>
</html>

header.jsp 中主要是 meta、script 和 link 标签,适合放在 <head> 内。这里的 header 只是 Tiles 属性名,不会自动对应 HTML 的 <head>。

如果 popupTemplate.jsp 只插入了 body,可能出现正文正常显示,但公共资源没有进入最终 HTML 的情况。

2. 确认弹窗请求经过了 Tiles 视图解析

Controller 应返回与目标 definition 对应的逻辑视图名。对于这份配置,检查返回值是否为:

return "svManager/registPj/svProjectList";

同时检查 Spring MVC 的视图解析配置,确认这个视图名确实由 Tiles 处理。如果请求通过其他解析器直接渲染正文 JSP,或者 Controller 直接 forward 到正文 JSP,popBase 和 popupTemplate.jsp 都不会参与此次渲染。

可以结合 Controller 返回值、服务端日志和实际响应内容,确认最终使用的模板。tiles.xml 中存在同名 definition,并不能证明当前请求使用了它。

3. 用弹窗的 HTML 响应区分故障位置

打开开发者工具,选中弹窗对应的页面请求,在 Response 中搜索 jquery.min.js、semantic.js 或 semantic.css。如果是独立浏览器窗口,需要查看该窗口的开发者工具。

响应中的情况下一步检查
没有对应的 script、link 标签检查模板是否插入 header,以及请求是否经过目标 Tiles definition
标签存在,但 URL 指向错误位置检查应用的 context path 和资源路径
有资源请求,但返回 404、403 或 HTML 页面检查静态资源映射、访问限制及响应内容
资源成功返回,但功能仍不可用检查 Console、脚本执行顺序和初始化代码

查看 Network 时,先开启记录,再重新打开或刷新弹窗,并清除可能隐藏请求的过滤条件。没有看到请求,不能直接证明 Tiles 配置有误。

4. 检查以 / 开头的资源路径

原代码使用了:

<script type="text/javascript" src="/js/jquery.min.js"></script>

这里的 /js/jquery.min.js 从当前站点根路径开始解析。如果应用部署在 /myapp 下,而资源位于该应用内,实际需要的路径通常是 /myapp/js/jquery.min.js。

对于存放在当前 Web 应用中的资源,可以使用 context path:

<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/common.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/viewMessage.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/dist/semantic.js"></script>

<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/common.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/dist/semantic.css">

资源 URL 需要根据实际位置判断。如果资源本来就由站点根路径统一提供,应保留实际部署所需的 URL,不能一概添加 context path。

路径错误通常仍会产生请求,只是请求发往了错误地址。因此,应先确认标签是否进入 HTML,再处理路径问题。

5. 注意弹窗的加载方式

如果弹窗是通过 window.open() 打开的独立页面,它有自己的文档,需要自行加载所需的 JS 和 CSS,不能直接沿用父窗口的资源。

如果弹窗通过 Ajax 在当前页面加载 HTML 片段,还要检查返回的是完整布局还是正文片段,以及所用的插入方式是否会执行片段中的脚本。此时通常应由宿主页加载公共依赖,再在内容插入后执行初始化逻辑。

直接在弹窗正文中引入 jQuery 后能够使用,说明这种加载方式有效,但还不能确定原来的问题是模板遗漏、视图解析还是资源路径。修复公共布局后,应移除临时添加的重复依赖,并保持 jQuery 在依赖它的脚本之前加载。

备注:内容仅供参考。