본문 바로가기
dev/javascript

[javascript] 자바스크립트 fetch로 formdata post 보내기

by 최연탄 2022. 9. 1.
728x90
반응형

폼 데이터를 전송할 때 JavaScript의 fetch api를 사용하면 데이터 전송을 세밀하게 제어할 수 있습니다. 이는 submit과 동시에 데이터를 전송하고 새 페이지로 리다이렉션하는 표준 HTML 동작으로 처리하지 않고 최소한의 dom 조작으로 그냥 백그라운드에서 더이터 전송을 처리하고 효율적으로 통신할 수 있도록 합니다.

준비

post 메시지를 보내는 작업을 하기 전에 post로 보낼 form이 필요합니다. 간단하게 사용자 이름과 비밀번호 두 개의 입력필드를 가지는 양식을 만들어보겠습니다. 먼저 index.html 파일을 만들고 다음의 코드를 입력합니다.

<html>
<body>
  <form id="form">
    <input name="username" type="text">
    <input name="password" type="password">
    <button type="submit">Submit</button>
  </form>
</body>
</html>

위 코드를 실행하면 다음과 같은 화면을 얻게됩니다.

form에 submit 이벤트 추가

먼저 폼 항목을 선택하고 submit 이벤트 리스너를 추가하여 submit 이벤트를 수신합니다. 그리고 이벤트 객체의 preventDefault() 메소드를 적용하여 form이 새창으로 리다이렉트하는 HTML 기본 동작을 수행하지 않도록 합니다.

<html>
<body>
  <form id="form">
    <input name="username" type="text">
    <input name="password" type="password">
    <button type="submit">Submit</button>
  </form>

  <script>
    const form = document.getElementById('form');

    form.addEventListener('submit', (e) => {
      e.preventDefault();
    });
  </script>
</body>
</html>

FormData 전송

먼저 내장된 FormData 객체를 생성합니다. 여기서 form 항목을 FormData 객체에 할당하면 key, value 쌍으로 form 항목의 값을 읽어올 수 있습니다.

<html>
<body>
  <form id="form">
    <input name="username" type="text">
    <input name="password" type="password">
    <button type="submit">Submit</button>
  </form>

  <script>
    const form = document.getElementById('form');

    form.addEventListener('submit', (e) => {
      e.preventDefault();

      const payload = new FormData(form);

      console.log([...payload]);
    });
  </script>
</body>
</html>

위의 코드를 실행하여 입력필드에 값을 넣고 sumbit을 누르면 다음과 같은 로그를 볼 수 있습니다.

이제 서버로 전송할 자료를 만들었으니 fetch api를 통해 실제로 데이터를 보내도록 하겠습니다. 여기서 사용할 테스트 서버는 포스트를 참고하면 됩니다.

<html>
<body>
  <form id="form">
    <input name="username" type="text">
    <input name="password" type="password">
    <button type="submit">Submit</button>
  </form>

  <script>
    const form = document.getElementById('form');

    form.addEventListener('submit', (e) => {
      e.preventDefault();

      const payload = new FormData(form);

      fetch('http://localhost:8080', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: payload,
      })
      .then(res => res.json())
      .then(data => console.log(data));
    });
  </script>
</body>
</html>

fetch api의 매개변수로 서버의 주소를 넣어준 다음 post 전송을 위해 옵션 값의 method 속성을 POST로 설정해 주었습니다. HTTP 헤더 속성도 지정해주고 body에 FormData 객체를 넣어서 전송하면 됩니다. 비동기적으로 fetch의 결과가 서버로 부터 도착하면 첫 번째 then이 실행되고 여기서 결과값을 json 형태로 수정한 다음 수정된 값을 콘솔에 출력하도록 했습니다. 다음은 위 코드의 실행 결과입니다.

URL-enconded 문자열 전송

post 메시지를 보낼 때 데이터로 FormData 뿐 아니라 URL-enconded 문자열도 보낼 수 있습니다. 이 방식은 문자열로만 이루어진 데이터를 전송하는데 더 효과적입니다. 이를 위해 내장된 URLSearchParams 객체를 사용하여 데이터를 관리할 수 있습니다.

<html>
<body>
  <form id="form">
    <input name="username" type="text">
    <input name="password" type="password">
    <button type="submit">Submit</button>
  </form>

  <script>
    const form = document.getElementById('form');

    form.addEventListener('submit', (e) => {
      e.preventDefault();

      const formData = new FormData(form);
      const payload = new URLSearchParams(formData);

      fetch('http://localhost:8080', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: payload,
      })
      .then(res => res.json())
      .then(data => console.log(data));
    });
  </script>
</body>
</html>

그저 FormData 객체를 URLSearchParams에 넘기면 알아서 처리해줍니다. 다음 이미지로 서버의 응답 값을 확인할 수 있습니다.

요약

JavaScript의 Fetch API를 사용하여 폼 데이터를 전송하면 HTML의 기본 폼 전송 동작에 의존하지 않고 데이터 전송 프로세스에 대한 완전한 유연성을 얻을 수 있습니다.

관련 글

자바스크립트 파일 업로드 (form post)

반응형

댓글