Spring boot + React Whitelabel Error Page

 스프링부트와 리액트를 연동해서 API 테스트 진행 중 다음 화면과 같은 에러 페이지가 발생했다.

 

 이때까지 스프링 + 리액트를 연동해서 프로젝트를 진행했을 때 한번도 이런 오류를 발견한 적이 없었는데.. 

 

 Whitelabel Error Page는 Spring Boot의 기본 에러 페이지이다. 클라이언트가 Spring Boot 서버로 요청을 보냈지만, 해당 요청을 처리할 경로가 매핑되지 않았거나 예외가 발생한 경우 나타나는데 해당 페이지 콘솔을 보면 404에러가 뜨는것이 보인다.

 원인은 총 4가지의 경우를 생각해볼 수 있는데,

1. React SPA(Single Page Application) 라우팅 문제

 -  React는 SPA로 동작하며, 클라이언트 측에서 라우팅을 처리하는데 브라우저에서 React 특정 경로로 직접 접근 or 새로고침을 하면 Spring Boot로 요청이 전달된다.  Spring Boot가 해당 경로를 매핑을 가지고 있지 않으면 해당 오류가 뜬다.

 

2. 프론트엔드 요청 경로 문제

 - React에서 Spring Boot API를 호출할 때, 잘못된 경로로 요청을 보낸 경우이다.

 

3. Proxy 설정 누락 또는 CORS 문제

 - React 개발 서버에서 Spring Boot 서버로 요청할 때, 프록시 설정이 없거나 CORS 정책이 제대로 설정되지 않았다면 요청이 실패하고 React가 잘못된 경로로 리다이렉트되어 해당 에러가 나타날 수 있다.

 

4. Spring Boot의 index.html 미포워딩 문제

 - 프로덕션 환경에서 React를 빌드 후 Spring Boot의 정적 리소스(/static)로 배포한 경우, React 라우터의 경로를 Spring Boot가 처리하지 못하면 해당 에러가 발생한다. Spring Boot는 정적 파일(예: index.html)을 리턴하지 않고 요청 경로가 없다고 간주.

 

 나의 경우엔 API 코드를 확인해서 경로가 맞는 것을 확인하였고, React에서 setupProxy 설정 및 Spring에서 WebConfig를 통해 CORS문제가 해결된 상태였다.

 그래서 4번이라 생각했는데 해결 방법을 잘 모르겠어서 지난 프로젝트들을 살펴본 결과 Spring 프로젝트의 resources 폴더에 static 폴더가 없는데 이번 프로젝트에는 해당 폴더가 존재했다. 그래서 그 폴더를 지우니까 해당 오류가 해결되었다..?

해결된 이유를 설명하자면,

 Spring Boot는 src/main/resources/static 폴더에 있는 파일을 정적 리소스로 서빙하는데 React 빌드 파일을 이 폴더에 복사하면 Spring Boot는 해당 파일을 그대로 반환한다. 근데 React는 SPA으로 동작하기 때문에 특정 경로를 직접 접근하면 Spring Boot가 해당 경로를 정적으로 처리하려고 시도한다. 

리액트는 SPA로 모든 경로 요청을 index.html로 포워딩하여 클라이언트 측 라우팅을 처리해야 하는데 static 폴더에 리소스가 남아 있으면, Spring Boot는 해당 경로를 React 라우터로 넘기지 않고, 리소스 파일을 찾으려 시도한다. 만약 Spring Boot가 정적 파일을 찾지 못하면 해당 에러가 나타난다.

 그래서 static 폴더를 지움으로써 Spring Boot는 정적 파일을 찾지 않고 모든 경로 요청을 처리하려고 시도하며, React 라우터로 요청을 올바르게 전달할 수 있는 환경이 되었기 때문에 문제가 해결된 것이다.

 

static 폴더를 제거하여 Spring Boot가 정적 리소스를 서빙하려는 기본 동작을 하지 않게 되어 해결된 것!