본문 바로가기
dev/javascript

[javascript] 자바스크립트 fetch로 JSON post (then, async, await)

by 최연탄 2023. 2. 1.
728x90
반응형

참고: https://ultimatecourses.com/blog/fetch-api-post-json

이 포스트에서는 fetch api를 사용하여 JSON 데이터를 서버로 post하는 방법을 알아보겠습니다.

이를 위해 먼저 form과 submit으로 이루어진 HTML 파일을 만들어 fetch로 백엔드 서버에 데이터를 post하도록 하겠습니다. 먼저 post할 데이터를 잡기위해 form에 name 속성을 줍니다.

<form name="fetch">
  <input type="text" name="message" placeholder="Tell me something!">
  <button type="submit">Submit</button>
</form>

form의 참조를 잡기위해 document.forms를 사용하여 name="fetch"인 항목을 찾습니다.

const form = document.forms.fetch;

const handleSubmit = (e) => {
  e.preventDefault();
};

form.addEventListener('submit', handleSubmit);

데이터 처리를 위해 submit 이벤트를 핸들링할 이벤트 리스너를 설정했습니다.

다음으로 아래 코드는 서버에 보낼 데이터를 얻기위해 JSON 값을 가져오는 것 입니다. 일단 자세한 사항은 건너뛰고 Object.fromEntries와 new FormData를 사용해 form의 값을 직렬화합니다. 위에서 만든 form에는 name="message"인 input이 하나 있고 이를 body 변수에 저장합니다. 큰 줄기로 설명하면 e.target을 사용하여 key/value 쌍의 객체를 만들고 이 객체를 서버로 전송할 수 있도록 문자열화 하는 것 입니다.

const handleSubmit = (e) => {
  e.preventDefault();

  const body = JSON.stringify(Object.fromEntries(new FormData(e.target)));

  console.log(body);
};

다음으로 로직의 추상화를 위해 새로운 함수를 만들고 fetch 명령어를 사용합니다.

const postForm = (body) => {
  return fetch('http//test.xyz/post', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body
  });
};

여기서 일반적인 fetch 호출과 다른점은 무엇일까요? 위 코드에서 보이는 바와 같이 Content-Type 헤더를 지정했고 그 값으로 application/json을 설정했습니다. method: 'POST' 하는 것도 잊으면 안됩니다.

이 함수에서 서버로 보낼 데이터 body는 매개변수로 받았습니다. 이는 서버에 보낼 내용을 동적으로 처리할 수 있게하고 fetch로 실제 값을 전송할 수 있도록 합니다.

이제 이벤트핸들러 함수에 fetch api로 부터 리턴받은 promise를 처리하기 위해 .then()을 추가합니다.

const handleSubmit = (e) => {
  e.preventDefault();

  const body = JSON.stringify(Object.fromEntries(new FormData(e.target)));
  
  postForm(body)
    .then(res => res.json())
    .then(data => console.log(data.json));
};

위의 코드에서 주의할 점은 promise .then()으로 받은 res 값을 res.json()으로 리턴해주는 작업을 해야합니다. 이를 처리하지 않으면 결과 값에 에러가납니다. res.json() 까지 처리한 promise에서 서버가 보내준 값을 얻을 수 있습니다. 이를 확인하기 위해 data 변수를 console.log()로 확인해 보았습니다.

handleSubmit 함수에서 async, await을 사용해 데이터를 처리할 수도 있습니다.

const handleSubmit = async (e) => {
  e.preventDefault();

  const body = JSON.stringify(Object.fromEntries(new FormData(e.target)));

  const res = await postForm(body);
  const data = await res.json();

  console.log(data.json);
};

async, await 패턴이 비동기 코드를 동기화하여 처리하도록 fetch api와 잘 맞아떨어지는 것을 확인할 수 있습니다. 또한 이 패턴을 사용하면 .then()을 사용한 코드 중첩을 깨끗하게 정리할 수 있습니다.

전체 코드

HTML

<form name="fetch">
  <input type="text" name="message" placeholder="Tell me something!">
  <button type="submit">Submit</button>
</form>

JavaScript

const form = document.forms.fetch;

const postForm = (body) => {
  return fetch('http//test.xyz/post', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body
  });
};

const handleSubmit = async (e) => {
  e.preventDefault();

  const body = JSON.stringify(Object.fromEntries(new FormData(e.target)));

  const res = await postForm(body);
  const data = await res.json();

  console.log(data.json);
};

form.addEventListener('submit', handleSubmit);

관련 글

JavaScript 파일 업로드 (form post)

JavaScript Fetch API 사용 방법

JavaScript console.log() 사용 방법

반응형

댓글