Spring Boot无法加载Vite构建的React子路由静态资源问题求助
解决思路与方案
核心问题分析
你遇到的两个问题本质上是SPA(单页应用)在Spring Boot静态资源托管下的典型适配问题:
- 子路由刷新404:Spring Boot默认不会将非静态资源路径转发到
index.html,导致刷新子路由时直接返回Whitelabel错误页 - 子路由下CSS加载失败:Vite默认使用相对路径打包资源,子路由页面中浏览器会以当前路由为基础请求资源(如
/route/routetwo/assets/xxx.css),但实际资源在根目录的/assets/下
一、解决SPA路由Fallback问题
需要让Spring Boot将所有非API、非静态资源的请求转发到index.html,由React路由处理页面跳转。
方案1:通过WebMvcConfigurer配置视图控制器
创建Spring配置类:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class SpaRouteConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { // 匹配所有非静态资源路径,转发到index.html registry.addViewController("/**") .setViewName("forward:/index.html"); // 排除静态资源路径,避免拦截assets下的文件请求 registry.addViewController("/assets/**") .setViewName("forward:/assets/**"); } }
方案2:通过控制器映射处理Fallback
创建专门的Fallback控制器:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class SpaFallbackController { // 匹配所有无后缀的GET请求(排除API、静态资源) @GetMapping(value = "/**/{path:[^.]*}") public String forwardToIndex() { return "forward:/index.html"; } }
二、解决子路由下资源加载路径问题
修改Vite配置,强制资源使用根目录绝对路径,避免子路由下的相对路径错误。
修改vite.config.js/ts:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], // 设置base为根目录绝对路径,确保资源请求从/开始 base: '/', build: { outDir: 'dist' } })
执行vite build重新构建前端,将新的dist目录复制到src/main/resources/static下。此时index.html中的资源路径会变成/assets/index-${HASH}.css,无论当前路由是什么,都会从根目录请求资源。
三、验证静态资源托管与Docker构建
- 确认Spring Boot默认静态资源配置生效:Spring会自动托管
src/main/resources/static目录,/assets/xxx请求会映射到static/assets/xxx,无需额外配置 - 检查Docker构建逻辑:确保构建过程中正确将前端
dist目录复制到Spring的static目录。例如Maven可添加插件自动复制:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.1</version> <executions> <execution> <id>copy-frontend-dist</id> <phase>process-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.outputDirectory}/static</outputDirectory> <resources> <resource> <directory>../frontend/dist</directory> <filtering>false</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin>
内容的提问来源于stack exchange,提问作者numbersgoup
相关产品推荐
相关产品推荐

