[Web] 새로고침하면 초기화면으로? window.history.replaceState가 원인이었다
브라우저 새로고침시 초기화면(list)로 돌아가버리는 문제, 한 줄 주석이 해결했다
혹시 화면 작업하다가 뒤로가기는 잘 되는데 새로고침 누르니까
갑자기 list 화면으로 튕겨버린 경험 있으신가요?
저도 최근에 겪었던 문제인데, 원인은 의외로 간단했습니다.

문제 발견: replaceState가 파라미터를 삭제
해결 과정: 코드 한 줄의 차이
pushState vs replaceState 차이점
SPA 히스토리 관리 팁
작업환경 : 전자정부프레임워크(스프링 프레임워크), JSP, JavaScript
문제 발생: 새로고침(F5) 시 초기페이지로 돌아감
초기에 list 페이지에서 -> view 페이지로 이동, 이후 view에서 새로고침 -> 새로고침이 현재 view 페이지가 아닌 초기페이지인 list로 이동 문제 발생
문제 발견: replaceState가 파라미터를 삭제
웹 애플리케이션을 개발하다 보면 URL 관리가 생각보다 까다롭습니다.
특히 window.history.replaceState 같은 메서드를 사용할 때는 더욱 신경 써야 하죠.
이번 사례에서 발견된 문제는 이렇습니다.
view.jsp 파일에 다음과 같은 코드가 있었어요.
window.history.replaceState({}, null, location.pathname);
이 코드의 목적은 URL을 깔끔하게 만들려던 것이었는데요.
문제는 location.pathname만 남기고 쿼리 파라미터를 모두 지워버린다는 점이었습니다.
그래서 mode, c_invdate, c_invseq 같은 필수 파라미터들이 사라졌고,
사용자가 F5를 누르거나 새로고침하면 Controller가 파라미터 없이 호출됐습니다.
Controller는 파라미터가 없으니 default case로 처리해서 list 페이지를 보여주게 된 거죠.
해결 과정: 코드 한 줄의 차이
해결 방법은 정말 간단했습니다.
문제의 코드를 주석 처리하는 것만으로 충분했어요.
정상적으로 새로고침이 되는 다른 모듈을 확인해보니 view.jsp에 이 코드가 아예 없었고,
그쪽은 새로고침해도 정상적으로 작동했거든요.
// [2025-10-24] 브라우저 새로고침 시 list로 리다이렉트되는 문제 해결
// window.history.replaceState({}, null, location.pathname);
replaceState는 현재 히스토리만 교체하고 새로운 항목을 추가하지 않습니다.
덕분에 뒤로가기 스택은 유지되지만, URL 파라미터까지 제거하면 문제가 생기는 거죠.
새로고침할 때 브라우저는 현재 URL로 페이지를 다시 요청합니다.
파라미터가 없으면 서버는 어떤 데이터를 보여줘야 할지 몰라서 기본 페이지(list)로 보내버리는 겁니다.
즉 list -> view 페이지로 이동, 이후 view에서 새로고침 -> list로 이동 문제 발생, 원인은 js부분에 replaceState()가 있어서 생긴 문제 였습니다.
// replaceState 이렇게 주석 처리 하니 문제 해결되었습니다.
AI로 개발하다 보니 문제가 어디가 문제인지 모르고 한참 헤맸네요. 이 글도 어느정도 AI가 써준겁니다.
아래는 AI가 정리해준 글
pushState vs replaceState 차이점
History API를 제대로 쓰려면 두 메서드의 차이를 알아야 합니다.
| 구분 | pushState | replaceState |
|---|---|---|
| 히스토리 추가 | 새 항목을 스택에 추가 | 현재 항목만 교체 |
| 뒤로가기 | 이전 페이지로 이동 가능 | 교체 전 페이지는 접근 불가 |
| 사용 시나리오 | 페이지 이동 기록 유지 | 폼 제출 후 재제출 방지 |
| 새로고침 영향 | 추가된 URL로 재요청 | 교체된 URL로 재요청 |
pushState는 히스토리를 쌓아갑니다.
배열에 push하듯이 계속 추가되는 방식이죠.
history.pushState({page: 1}, '', '/page1');
history.pushState({page: 2}, '', '/page2');
// 뒤로가기 누르면 /page1로 돌아감
반면 replaceState는 마지막 항목만 바꿉니다.
array[array.length-1] = newValue 같은 느낌이에요.
history.pushState({page: 1}, '', '/page1');
history.replaceState({page: 2}, '', '/page2');
// 뒤로가기 누르면 /page1 이전으로 돌아감
게시글 작성 후 완료 페이지로 이동할 때 replaceState를 쓰면
뒤로가기를 눌러도 작성 페이지로 돌아가지 않습니다.
로그인 완료 후에도 마찬가지죠.
SPA 히스토리 관리 팁
Single Page Application에서 히스토리 관리는 필수입니다.
몇 가지 실전 팁을 정리해봤어요.
1. popstate 이벤트 리스너 활용하기
뒤로가기나 앞으로가기를 누를 때 발생하는 이벤트를 잡아서 처리할 수 있습니다.
window.addEventListener('popstate', function(event) {
console.log('State:', event.state);
// 이전 페이지 렌더링 로직
});
단, pushState나 replaceState 호출 시에는 popstate가 발생하지 않으니 주의하세요.
2. URL 파라미터는 꼭 보존하기
필수 데이터가 파라미터에 있다면 replaceState 사용 시 조심해야 합니다.
location.pathname만 쓰지 말고 search까지 포함하세요.
// 안 좋은 예
history.replaceState({}, '', location.pathname);
// 좋은 예
history.replaceState({}, '', location.pathname + location.search);
3. state 객체에 필요한 데이터 저장
pushState나 replaceState의 첫 번째 인자로 데이터를 저장할 수 있습니다.
나중에 history.state로 꺼내 쓸 수 있어서 편리해요.
history.pushState({
mode: 'view',
invdate: '20251024',
invseq: '001'
}, '', '/view');
// 나중에 접근
console.log(history.state.mode); // 'view'
4. 서버 사이드 렌더링 대응
History API로 URL을 바꾸면 새로고침 시 서버에 해당 경로가 없어서 404 에러가 날 수 있습니다.
서버 설정에서 모든 경로를 index.html로 연결하거나,
실제 라우팅 경로를 서버에도 구현해야 합니다.
Q&A
Q. replaceState 쓰면 뒤로가기가 안 되나요?
아닙니다. 뒤로가기 자체는 됩니다.
단지 현재 항목이 교체될 뿐이라 교체 전 상태로는 못 돌아가요.
Q. 히스토리를 완전히 삭제할 수 있나요?
JavaScript로는 브라우저 히스토리를 직접 삭제할 수 없습니다.
보안상의 이유로 클라이언트에서 권한이 없거든요.
Q. React Router도 이 방식을 쓰나요?
맞습니다. React Router 같은 라이브러리들이 내부적으로 History API를 활용합니다.
더 편리한 인터페이스로 감싸서 제공하는 거죠.
결국 이번 케이스는 불필요한 URL 정리 코드가 오히려 독이 된 사례였습니다.
코드를 추가할 때는 부작용까지 꼼꼼히 생각해봐야겠어요.
새로고침 동작 확인은 개발 단계에서 필수입니다.
사용자들은 언제든 F5를 누를 수 있으니까요.