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

ReactJS与Spring Boot单体应用整合时页面刷新出现白标错误问题

React + Spring Boot 单体应用刷新出现白标页的排查与解决方案

问题根因

该问题本质是React客户端路由和Spring Boot服务端路由匹配逻辑冲突导致:

  • React使用BrowserRouter做客户端路由时,路径变化是浏览器端通过History API实现的,不会发起真实的服务端请求
  • 页面刷新时,浏览器会直接向Spring Boot发起当前完整路径的GET请求,而Spring Boot没有对应路径的接口/资源映射,就会返回默认的404白标页

排查步骤

  • 确认React打包后的build目录,是否正确放到Spring Boot的src/main/resources/static目录或你自定义的静态资源目录下,静态资源路径配置无错误
  • 确认React路由模式:检查是否用的是BrowserRouter而非HashRouter,HashRouter生成带#的路径,刷新时不会触发服务端请求,一般不会出现该问题
  • 直接在浏览器地址栏输入非首页的前端路由路径(比如http://你的服务地址/dashboard),如果直接返回白标页,即可确定是路由匹配冲突问题

解决方案

方案1:配置Spring Boot视图跳转规则(最常用)

新增Web配置类,将所有非接口、非静态资源的请求都转发到React入口文件index.html,交给客户端处理路由:

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 WebConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 匹配一级路径,排除带后缀的静态资源请求
        registry.addViewController("/{path:[^\\.]*}")
                .setViewName("forward:/index.html");
        // 匹配多级嵌套路由
        registry.addViewController("/**/{path:[^\\.]*}")
                .setViewName("forward:/index.html");
    }
}

如果你的后端接口有统一前缀(比如/api),该规则会自动跳过接口请求,不会影响接口调用。

方案2:自定义ErrorController捕获404请求转发

如果不想修改视图规则,也可以自定义错误控制器捕获404请求,统一转发到index.html:

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;

@RestController
public class CustomErrorController implements ErrorController {
    @RequestMapping("/error")
    public ResponseEntity<?> handleError(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == HttpStatus.NOT_FOUND.value()) {
            return ResponseEntity.status(HttpStatus.OK)
                    .body("forward:/index.html");
        }
        // 其他错误状态码正常返回
        return ResponseEntity.status(statusCode).body("请求错误");
    }
}

注:Spring Boot 3.x版本中,错误状态码的获取key改为jakarta.servlet.error.status_code,对应替换即可。

方案3:前端改用HashRouter(改造成本最低)

如果不想修改服务端配置,可以直接把React的路由模式换成HashRouter,生成的路径会自动携带#,刷新时不会向服务端请求#后面的路径,也能解决问题:

// 把原来的BrowserRouter替换为HashRouter即可
import { HashRouter as Router, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <Router>
      <Routes>
        {/* 原有路由规则保持不变 */}
      </Routes>
    </Router>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:15:02