[Java Spring] fetch로 인해 발생한 리다이렉트 문제

khj·2025년 4월 8일

Java

목록 보기
7/11
post-thumbnail

Spring 프로젝트에서 회원가입 기능을 구현하는 과정에서, fetch를 사용해 데이터를 전송하던 중 기대한 대로 redirect가 동작하지 않는 문제를 경험했다.


문제 상황

초기 회원가입 기능의 컨트롤러는 다음과 같이 구성되어 있었다:

@PostMapping("/signup")
public String signup(@RequestBody MemberSignUpForm form) {
    Member member = memberService.signUp(form);
    return "redirect:/";
}

프론트엔드에서는 JavaScript fetch를 사용하여 데이터를 전송하고 있었다:

document.getElementById("signupForm").addEventListener("submit", function(event) {
    event.preventDefault();

    const formData = {
        ...
    };

    fetch("/signup", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify(formData),
        redirect: "manual"
    })
    .then(response => {
        console.log("Response:", response);
        window.location.href = "/login";
    })
    .catch(error => {
        console.error("Error:", error);
        alert("회원가입 중 문제가 발생했습니다.");
    })
});

문제가 발생한 이유

Spring에서 redirect:/login과 같은 리다이렉트는 서버에서 HTTP 302 응답을 클라이언트에게 전달하여 브라우저가 새로운 요청을 하도록 유도하는 방식이다.
하지만 fetch를 사용하면 이 리다이렉트가 브라우저 레벨에서 자동으로 동작하지 않고, fetch 내부에서만 처리된다.
즉, JavaScript 코드가 redirect 응답을 받아도, 브라우저는 실제로 리다이렉트를 수행하지 않는다.

게다가 서버 측에서 RedirectAttributes를 사용하여 FlashAttribute를 전달하는 것도 fetch 방식에서는 사용할 수 없다.
이로 인해 회원가입 성공/실패 여부에 따른 알림 메시지 처리도 어려웠다.


해결 방법

프론트엔드의 fetch 요청을 제거하고, 기본적인 HTML

제출 방식을 사용하도록 변경했다.

<form action="${pageContext.request.contextPath}/signup" method="post">

수정된 컨트롤러

@PostMapping("/signup")
public String signup(@ModelAttribute MemberSignUpForm form, Model model) {
    try {
        Member member = memberService.signUp(form);
        model.addAttribute("message", "회원가입이 완료되었습니다.");
        return "member/login";
    } catch (RuntimeException e) {
        model.addAttribute("message", e.getMessage());
        return "member/signup";
    }
}

컨트롤러에서는 회원가입 도중 예외가 발생하는지 여부에 따라 login.jsp 혹은 signup.jsp 페이지를 반환하며, message 속성을 통해 성공/실패 메시지를 뷰로 전달한다.

profile
Spring, Django 개발 블로그

0개의 댓글