[Javascript] Axios로 요청 보내기

이지연·2026년 1월 9일

Axios로 POST 요청을 보내는 방식은 크게 HTML 기본 form 전송JS로 직접 Axios를 사용하는 방식(JSON, x-www-form-urlencoded, FormData)로 나눌 수 있다.


0) HTML form 기본 POST 전송

브라우저는 자바스크립트 없이도 <form> 태그만으로 POST 요청을 보낼 수 있다.
이때 핵심은 action, method, enctype 세 속성이다.

0-1. x-www-form-urlencoded 기본 전송

<form action="http://localhost:8081/post/register2"
      method="post"
      enctype="application/x-www-form-urlencoded">
  <div class="mb-2">
    <label class="form-label" for="ftitle">제목</label>
    <input class="form-control" id="ftitle" name="title" />
  </div>
  <div class="mb-3">
    <label class="form-label" for="fcontents">내용</label>
    <textarea class="form-control" id="fcontents" name="contents" rows="4"></textarea>
  </div>
  <button class="btn btn-dark" type="submit">폼 제출(POST)</button>
</form>
  • method="post": POST 요청으로 전송.
  • enctype="application/x-www-form-urlencoded"
    • 기본값으로, name=value&name2=value2 형태로 body를 인코딩한다.
  • 서버에서는 일반적인 폼 파라미터(@RequestParam, @ModelAttribute) 형태로 받기 좋다.

0-2. 파일 업로드 포함 (multipart/form-data)

<form action="http://localhost:8081/post/registerWithFile"
      method="post"
      enctype="multipart/form-data">
  <div class="mb-2">
    <label class="form-label" for="ftitle2">제목</label>
    <input class="form-control" id="ftitle2" name="title" />
  </div>
  <div class="mb-2">
    <label class="form-label" for="fcontents2">내용</label>
    <textarea class="form-control" id="fcontents2" name="contents" rows="4"></textarea>
  </div>
  <div class="mb-3">
    <label class="form-label" for="ffile">첨부파일</label>
    <input class="form-control" id="ffile" name="file" type="file" />
  </div>
  <button class="btn btn-dark" type="submit">파일 포함 제출</button>
</form>
  • enctype="multipart/form-data"
    • 텍스트 + 파일을 함께 보내는 전형적인 방식.
  • 서버에서는 @RequestParam MultipartFile file 같은 형태로 처리.

요약:

  • JS 없이 빠르게 폼만으로도 POST 가능.
  • 다만, 페이지 이동/새로고침 중심이라 SPA/리액티브 UX에는 한계가 있고, 이때 Axios 방식이 필요해진다.

1) Axios + JSON 방식 (가장 기본)

JS 객체를 만들어서 axios.post(url, data)에 넘기면, Axios가 기본적으로 JSON으로 직렬화해서 전송하는 패턴이다.

const onClickPostRegisterJson = async () => {
  try {
    const titleValue = document.getElementById("title").value;
    const contentsValue = document.getElementById("contents").value;

    const data = { title: titleValue, contents: contentsValue };

    await axios.post("http://localhost:8081/post/register1", data);

    window.location.href = "./post_list.html";
  } catch (error) {
    console.log(error);
    alert("예상치 못한 에러가 발생하였습니다.");
  }
};

그리고 HTML 입력 영역:

<div class="mb-2">
  <label class="form-label">제목</label>
  <input id="title" class="form-control" placeholder="테스트 제목" />
</div>
<div class="mb-3">
  <label class="form-label">내용</label>
  <textarea id="contents" class="form-control" rows="4" placeholder="테스트 내용"></textarea>
</div>
<button class="btn btn-dark" type="button" onclick="onClickPostRegisterJson()">
  JSON 방식으로 전송
</button>

정리 포인트

  • 헤더
    • Axios는 객체를 넘겼을 때 기본적으로 Content-Type: application/json으로 보내는 패턴으로 많이 사용된다.
  • 서버 측
    • 스프링 기준이면 @RequestBody DTO로 받는 케이스와 잘 맞는다.
  • 장점
    • JS 객체와 서버 DTO가 구조적으로 1:1 매핑되기 쉬워서 현대 REST API에서 가장 많이 쓰는 방식.

2) Axios + application/x-www-form-urlencoded

form 기본 인코딩과 같은 형식으로 보내고 싶다면, URLSearchParams를 사용해 key/value를 구성한 뒤 전송하면 된다.

const onClickPostRegisterUrlencoded = async () => {
  try {
    const titleValue = document.getElementById("title2").value;
    const contentsValue = document.getElementById("contents2").value;

    const params = new URLSearchParams();
    params.append("title", titleValue);
    params.append("contents", contentsValue);

    await axios.post("http://localhost:8081/post/register2", params, {
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
    });

    window.location.href = "./post_list.html";
  } catch (error) {
    console.log(error);
    alert("예상치 못한 에러가 발생하였습니다.");
  }
};

입력 영역:

<div class="mb-2">
  <label class="form-label">제목</label>
  <input id="title2" class="form-control" placeholder="테스트 제목" />
</div>
<div class="mb-3">
  <label class="form-label">내용</label>
  <textarea id="contents2" class="form-control" rows="4" placeholder="테스트 내용"></textarea>
</div>
<button class="btn btn-dark" type="button" onclick="onClickPostRegisterUrlencoded()">
  x-www-form-urlencoded 방식으로 전송
</button>

정리 포인트

  • URLSearchParams는 내부적으로 title=값&contents=값 형태의 쿼리 스트링을 만들어준다.
  • 헤더를 명시적으로 application/x-www-form-urlencoded로 맞춰주는 것이 관례상 깔끔하다.
  • 서버에서는 “전통적인 폼 파라미터”처럼 처리하고 싶을 때(기존 레거시, 서드파티 API 등) 이 방식을 사용하면 좋다.

3) Axios + FormData (multipart/form-data)

파일 업로드, 이미지, 복합 데이터 전송이 필요할 때는 FormData를 사용한다.

const onClickPostRegisterFormData = async () => {
  try {
    const titleValue = document.getElementById("title3").value;
    const contentsValue = document.getElementById("contents3").value;

    const formData = new FormData();
    formData.append("title", titleValue);
    formData.append("contents", contentsValue);

    await axios.post("http://localhost:8081/post/register3", formData);

    window.location.href = "./post_list.html";
  } catch (error) {
    console.log(error);
    alert("예상치 못한 에러가 발생하였습니다.");
  }
};

입력 영역:

<div class="mb-2">
  <label class="form-label">제목</label>
  <input id="title3" class="form-control" placeholder="테스트 제목" />
</div>
<div class="mb-3">
  <label class="form-label">내용</label>
  <textarea id="contents3" class="form-control" rows="4" placeholder="테스트 내용"></textarea>
</div>

<button class="btn btn-dark" type="button" onclick="onClickPostRegisterFormData()">
  FormData 방식으로 전송
</button>

<div class="mt-3 text-muted small">
  참고: 변수 이름을 <code>titleValue</code> / <code>contentsValue</code>로 일관되게 써주지 않으면,
  <code>data.append("title", title)</code>처럼 잘못된 변수를 넣어버려 값이 전송되지 않을 수 있다.
</div>

파일까지 포함하려면:

<input id="file3" class="form-control" type="file" />
const fileInput = document.getElementById("file3");
if (fileInput.files[0]) {
  formData.append("file", fileInput.files[0]);
}

정리 포인트

  • FormData를 Axios에 그대로 넘기면, 일반적으로 multipart/form-data로 전송된다.
  • 헤더에서 Content-Type을 직접 쓰지 않고 Axios/브라우저에게 맡기는 경우가 많다(경계(boundary) 자동 생성).
  • 서버에서는 @RequestPart + DTO, MultipartFile 조합으로 받는 패턴이 흔하다.

4) 언제 어떤 방식을 써야 할까?

간단히 비교하면:

상황권장 방식
SPA/REST API, JSON DTOAxios + JSON
기존 폼 파라미터 스타일 APIAxios + x-www-form-urlencoded (또는 form)
파일/이미지 포함Axios + FormData
간단한 페이지 전환형 폼순수 HTML form POST

5) 보완 요약

  • JSON 방식: Axios가 객체를 보낼 때 보통 JSON으로 직렬화해서 보내며, 서버에서는 @RequestBody와 잘 맞는다
  • urlencoded 방식: URLSearchParams + Content-Type 헤더를 명시해 “진짜 폼 인코딩”을 의도대로 맞춘다
  • FormData 방식:
    • 단순 텍스트 외에 파일을 추가할 때 input[type=file].files[0]로 꺼내서 append 해야 한다
    • Content-Type은 직접 건드리지 않고 브라우저/axios에 맡기는 것이 일반적이다
  • 공통: 변수 이름(titleValue, contentsValue)을 FormData/params 구성 시에 동일하게 사용하지 않으면 값이 서버로 안 가는 버그가 생기기 쉬우므로, 이름 일관성이 중요
profile
Eazy하게

0개의 댓글