본문 바로가기
SpringBoot

[springboot] HTML form 전송 vs JavaScript로 JSON 전송

by 개발LOG 2025. 11. 2.
반응형

🧩 1. HTML <form> 전송 방식

🔹 개요

  • 브라우저가 기본적으로 제공하는 폼 전송 기능 사용
  • <form> 태그의 action과 method 속성을 이용해 서버로 데이터를 전송
  • 전송 형식은 기본적으로 application/x-www-form-urlencoded 또는 multipart/form-data (파일 업로드 시)

🔹 예시 코드

<form action="/signup" method="POST">
  <label>아이디: <input type="text" name="username" /></label><br>
  <label>비밀번호: <input type="password" name="password" /></label><br>
  <button type="submit">회원가입</button>
</form>

 

🔹 서버 (Spring Boot Controller)

@ReauireArgsConstructor
@Controller
public class UserController {
	
    private final UserService userservice;
    
    @PostMapping("/user")
    public String signup(AddUserRequest request){
    	userservice.save(request);
    	return "redirect:/login";
    }
    
}

🔹 전송되는 데이터 (요청 예시)

POST /signup HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=kim123&password=1234

🔹 장점

✅ 브라우저 기본 기능 → 구현 간단
✅ 자바스크립트 없어도 동작 (접근성 높음)
✅ 서버 사이드 렌더링(SSR) 구조에 적합

🔹 단점

❌ 페이지 전체 새로고침 발생
❌ JSON 형태 아님 → API 서버에 보내기엔 불편
❌ 유효성 검사나 비동기 처리가 어렵다 (JS 필요)

 


🧩 2. JavaScript(JSON 전송) 방식 (예: fetch())

🔹 개요

  • JS로 직접 HTTP 요청을 만들어 서버에 보냄 (보통 fetch나 axios 사용)
  • 전송 형식: application/json
  • SPA(React, Vue 등)나 REST API 서버 통신에 많이 사용

🔹 예시 코드

<form id="signupForm">
  <label>아이디: <input type="text" id="username" /></label><br>
  <label>비밀번호: <input type="password" id="password" /></label><br>
  <button type="submit">회원가입</button>
</form>

<script>
document.getElementById("signupForm").addEventListener("submit", async (e) => {
  e.preventDefault(); // 폼 기본 전송 막기

  const data = {
    username: document.getElementById("username").value,
    password: document.getElementById("password").value
  };

  try {
    const response = await fetch("/signup", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data)
    });

    // HTTP 에러 상태 코드 처리 (ex. 400, 500)
    if (!response.ok) {
      throw new Error("서버 응답 오류 (" + response.status + ")");
    }

    const result = await response.json();
    alert(result.message);
    window.location.href = "/login"; // 성공 시 로그인 페이지 이동

  } catch (error) {
    console.error("회원가입 중 오류 발생:", error);
    alert("회원가입에 실패했습니다. 잠시 후 다시 시도해주세요.");
  }
});
</script>

🔹 서버 (Spring Boot Controller)

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

@RequiredArgsConstructor
@RestController
public class UserController {

    private final UserService userService;

    @PostMapping("/signup")
    public Map<String, String> signup(@RequestBody AddUserRequest request) {
        try {
            // 회원가입 로직 수행
            userService.save(request);

            // 성공 응답 JSON
            return Map.of("message", request.getUsername() + "님 회원가입 성공!");

        } catch (Exception e) {
            // 서버에서 예외가 발생한 경우
            return Map.of("message", "회원가입 중 오류가 발생했습니다. 다시 시도해주세요.");
        }
    }
}

🔹 전송되는 데이터 (요청 예시)

POST /signup HTTP/1.1
Content-Type: application/json

{"username": "kim123", "password": "1234"}

🔹 장점

✅ 페이지 새로고침 없이 비동기 요청 가능 (UX 향상)
✅ JSON으로 직접 통신 → API 서버 연동 편리
✅ 클라이언트 단 유효성 검사, 동적 UI와 쉽게 통합

🔹 단점

❌ JS 비활성화 시 동작 안 함
❌ 코드 구현이 더 복잡
❌ CORS 등 보안 설정 필요


⚖️ 비교 정리표

구분  HTML Form 전송 JS(JSON) 전송
요청 형식 application/x-www-form-urlencoded application/json
컨트롤러 어노테이션 @Controller @RestController
요청 데이터 처리 @RequestParam 혹은
dto일땐 @RequestParam 사용없이 자동 바인딩
@RequestBody
응답 형식 HTML View (Thymeleaf 등) JSON (API 응답) 
사용 목적 전통적 SSR 웹사이트 SPA, 프론트-백엔드 분리형 구조
장점 간단, JS 없이 동작 비동기, UX 좋음, API 친화적

 

반응형