Spring Boot 静态资源首次访问无样式问题排查
Contents
问题现象
在开发SSO登录页面时遇到一个奇怪的问题:
- 直接在浏览器地址栏输入
http://localhost:8080/sso/login访问,页面没有CSS样式 - 但是点击刷新按钮后,样式就正常显示了
- 这种"首次无样式,刷新后有样式"的现象很诡异
排查过程
最初怀疑是以下问题:
- ❌ Sa-Token拦截器配置问题 - 已排除静态资源路径
- ❌ Spring MVC静态资源配置问题 - 配置正确
- ❌ 浏览器缓存问题 - 尝试添加版本参数无效
- ❌ CSS文件路径问题 - 文件存在且内容正确
真正原因
通过浏览器开发者工具的Network面板发现,CSS文件的请求URL变成了:
http://localhost:8080/css/sso/login.css;jsessionid=8E5753F407FFFE8DF6116069A2207295根本原因:Spring Session的URL重写机制!
- 当浏览器首次访问时,Spring不确定是否支持Cookie
- 为了保证会话跟踪,Spring会在所有URL后面添加
;jsessionid=xxx - 这导致静态资源路径变成非法URL,服务器无法找到对应文件
- 刷新时浏览器已经建立Cookie,不再使用URL重写,所以正常
解决方案
在Spring配置类中添加ServletContextInitializer,禁用URL重写:
@Bean
public ServletContextInitializer servletContextInitializer() {
return new ServletContextInitializer() {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// 只使用Cookie跟踪会话,禁用URL重写
servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
log.info("已禁用URL重写,只使用Cookie跟踪会话");
}
};
}总结
- 问题本质:Spring Session的URL重写机制影响静态资源访问
- 解决思路:禁用URL重写,只使用Cookie进行会话跟踪
- 经验教训:遇到静态资源加载问题时,要检查实际的网络请求URL
- 适用场景:现代Web应用基本都支持Cookie,可以安全禁用URL重写
这个问题比较隐蔽,因为只在特定条件下出现(首次访问且无Cookie),容易被忽略。
