You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入Spring Boot项目的React路由无法正常工作问题排查

问题分析与解决方案

核心问题

  1. SPA路由未被Spring Boot转发:React作为单页应用,所有前端路由(如/login、/dashboard)需要Spring Boot转发到index.html,否则Spring会将这些路径视为后端API请求,返回404。
  2. Spring Security配置不匹配SPA场景:loginPage("/login")指向的后端端点不存在,导致404;同时明文密码未加密,不符合Spring Security的密码校验规则。
  3. 登录表单提交逻辑缺失:React登录页未正确向Spring Security的认证接口提交请求,导致登录流程无法触发。

解决方案步骤

1. 配置Spring Boot转发SPA路由

添加控制器,将所有前端路由请求转发到index.html,确保React路由能正常接管页面渲染:

@Controller
public class SpaForwardController {

    // 覆盖所有需要React路由处理的路径
    @GetMapping(value = {"/login", "/dashboard", "/logout"})
    public String forwardToIndex() {
        return "forward:/index.html";
    }
}

或者通过WebMvcConfigurer配置全局转发规则,更通用:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("forward:/index.html");
        registry.addViewController("/dashboard").setViewName("forward:/index.html");
        registry.addViewController("/logout").setViewName("forward:/index.html");
    }
}

2. 修正Spring Security配置

  • 调整登录页路径,确保Spring Security允许访问前端路由;
  • 添加密码编码器,解决明文密码不被允许的问题;
  • 修正退出跳转路径,避免logout后出现404;
  • 放行静态资源(React打包后的css、js等)。

修改后的安全配置:

@Configuration
@EnableWebSecurity
public class DefaultWebSecurityConfig extends WebSecurityConfigurerAdapter {

    // 声明密码编码器Bean
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                // 放行静态资源和登录页
                .antMatchers("/", "/login", "/static/**", "/css/**", "/js/**").permitAll()
                // 仅dashboard需要认证
                .antMatchers("/dashboard").authenticated()
                .anyRequest().permitAll()
                .and()
                .formLogin()
                // 前端登录页路径(已被转发到index.html)
                .loginPage("/login")
                // Spring Security默认的认证处理端点,前端表单需提交到这里
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/dashboard")
                .permitAll()
                .and()
                .logout()
                // 退出后跳转回登录页
                .logoutSuccessUrl("/login")
                .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // 使用加密后的密码(原密码为"user")
        auth.inMemoryAuthentication()
                .withUser("user")
                .password(passwordEncoder().encode("user"))
                .roles("employee");
    }
}

3. 调整React登录表单提交逻辑

确保登录表单以POST方法提交到/login,参数名使用Spring Security默认的username和password:

// Login组件示例
function Login() {
    const handleSubmit = (e) => {
        e.preventDefault();
        const formData = new FormData(e.target);
        
        fetch('/login', {
            method: 'POST',
            body: new URLSearchParams(formData),
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        }).then(response => {
            if (response.ok) {
                window.location.href = '/dashboard';
            } else {
                alert('登录失败,用户名或密码错误');
            }
        });
    };

    return (
        <div className="login-container">
            <form onSubmit={handleSubmit}>
                <div>
                    <label>用户名:</label>
                    <input type="text" name="username" required />
                </div>
                <div>
                    <label>密码:</label>
                    <input type="password" name="password" required />
                </div>
                <button type="submit">登录</button>
            </form>
        </div>
    );
}

4. 确认maven-frontend插件打包配置

确保插件将React打包后的build目录内容复制到Spring Boot的静态资源目录(src/main/resources/static),示例pom.xml配置:

<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.12.0</version>
    <executions>
        <execution>
            <id>install node and npm</id>
            <goals><goal>install-node-and-npm</goal></goals>
            <configuration>
                <nodeVersion>v16.18.0</nodeVersion>
                <npmVersion>8.19.2</npmVersion>
            </configuration>
        </execution>
        <execution>
            <id>npm install</id>
            <goals><goal>npm</goal></goals>
            <configuration><arguments>install</arguments></configuration>
        </execution>
        <execution>
            <id>npm run build</id>
            <goals><goal>npm</goal></goals>
            <configuration><arguments>run build</arguments></configuration>
        </execution>
        <execution>
            <id>copy built resources</id>
            <goals><goal>copy</goal></goals>
            <configuration>
                <from>target/reactapp/build</from>
                <to>src/main/resources/static</to>
            </configuration>
        </execution>
    </executions>
</plugin>

验证步骤

  1. 执行mvn clean package打包应用;
  2. 启动Spring Boot应用,访问http://localhost:8090/login,确认React登录页正常显示;
  3. 输入user/user登录,确认跳转到/dashboard;
  4. 执行退出操作,确认返回登录页。

内容的提问来源于stack exchange,提问作者user2810351

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 22:25:05