[JS] 비동기 HTTP 통신 (Ajax, Axios, Fetch)

Chanki Hong·2023년 7월 9일
0

JavaScript

목록 보기
23/30
post-thumbnail

비동기 HTTP 통신

  • 서버와 데이터를 주고받기 위한 비동기 HTTP 통신.
  • 비동기 통신은 페이지 새로고침 없이 서버와 통신하여 동적인 콘텐츠를 로드하고 업데이트하는 데 사용.
  • 주로 사용하는 비동기 HTTP 통신은 Ajax, Axios, Fetch.

비동기 통신의 필요성

  • 초기 정적(static) 웹에서 동적(dynamic)인 웹으로 페러다임 전환.
  • 동기적 통신은 완료될 때 화면의 깜빡임이 발생,
    • 예를 들면, 페이스북의 좋아요 증가 => 페이지 새로 고침(갱신)
  • 또한 용량이 클 수록 로딩 시간이 길어짐.
  • 비동기 통신은 깜빡임 없이(새로 고침이 필요없음) 데이터를 표현 할 수 있고,
  • 초기 화면 구성 등에서도 이점(빠름)을 가짐.
  • 또한 Lazy Loading 등 필요한 부분만 업데이트하고 불필요한 데이터 전송을 최소화.

Ajax(Asynchronous JavaScript and XML)

  • XMLHttpRequest 객체(Web APIs)를 이용해 구현.

GET 예제

// GET 요청 함수
function getData(url, callback) {
  const xhr = new XMLHttpRequest(); // XMLHttpRequest 객체 생성
  xhr.open('GET', url, true); // '(요청방식, URL, 비동기처리유/무)'를 의미함
  xhr.onload = () => {
    if (xhr.status === 200) {
      // 200은 정상통신
      const response = JSON.parse(xhr.responseText);
      callback(null, response);
    } else {
      // 200 이외의 상태.(404,500 등)
      const error = new Error('Error: ' + xhr.status);
      callback(error);
    }
  };
  // 오류 발생시
  xhr.onerror = () => {
    const error = new Error('Request failed');
    callback(error);
  };
  xhr.send();
}

// GET 요청 보내기
getData('API URL', (error, data) => {
  if (error) {
    console.error(error);
  } else {
    console.log(data);
  }
});

POST 예제

// POST 요청 함수
function postData(url, data, callback) {
  const xhr = new XMLHttpRequest(); // XMLHttpRequest 객체 생성
  xhr.open('POST', url, true); // '(요청방식, URL, 비동기처리유/무)'를 의미함
  xhr.setRequestHeader('Content-Type', 'application/json');
  xhr.onload = () => {
    if (xhr.status >= 200 && xhr.status < 300) {
      // 200, 201, 204 상태코드 => 성공처리
      const response = JSON.parse(xhr.responseText);
      callback(null, response);
    } else {
      const error = new Error('Error: ' + xhr.status);
      callback(error);
    }
  };
  // 오류 발생시
  xhr.onerror = () => {
    const error = new Error('Request failed');
    callback(error);
  };
  xhr.send(JSON.stringify(data));
}

// POST 요청 보내기
const newPost = {
  title: 'New Post',
  content: 'This is a new post content.',
};
postData('API URL', newPost, (error, data) => {
  if (error) {
    console.error(error);
  } else {
    console.log(data);
  }
});

Fetch API

  • Promise 기반.
  • ES6부터 추가된 Web APIs.
  • 에러 발생 시 response timeout이 없음.
  • body 속성을 사용하고, 문자열화 되어있음.
  • JSON <-> object/array 변환 필요.
  • reponse 객체가 "OK" 속성을 포함하면 성공.

GET 예제

fetch('API URL')
  .then((response) => {
    // 응답 객체의 response의 ok속성에 따라 성공 유/무 확인
    if (response.ok) {
      // 성공(ok속성)시 JSON 파싱 후 다음 then으로 전달
      return response.json();
    } else {
      throw new Error('Error: ' + response.status);
    }
  })
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });

POST 예제

fetch('API URL', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'New Post',
    content: 'This is a new post content.',
  }),
})
  .then((response) => {
    if (response.ok) {
      return response.json();
    } else {
      throw new Error('Error: ' + response.status);
    }
  })
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });

Axios(Promise-based HTTP 클라이언트)

  • Promise 기반.
  • 브라우저와 Node.js 환경에서 모두 사용할 수 있는 내장된 HTTP 클라이언트 활용.
  • data 속성을 사용하고, object(객체)를 포함.
  • JSON <-> object/array 자동으로 변환.
  • status: 200 또는 statusText: "OK" 라면 성공.
  • XSRF(사이트 간 요청 위조) 보호.
  • 요청(Request) 취소와 요청 TimeOut 설정 가능.
  • 라이브러리 설치 필요.
npm install axios
  • 프로젝트에 추가 필요.
// Vanilla 프로젝트에서 아래 태그를 HTML에 추가
<script src="./node_modules/axios/dist/axios.min.js"></script>
// React 프로젝트
import axios from 'axios'

GET 예제

axios
  .get('API URL')
  .then((response) => {
    // 성공시
    console.log(response.data);
  })
  .catch((error) => {
    // 실패시
    console.error(error);
  });

POST 예제

axios
  .post('API URL', {
    title: 'New Post',
    content: 'This is a new post content.',
  })
  .then((response) => {
    // 성공시
    console.log(response.data);
  })
  .catch((error) => {
    // 실패시
    console.error(error);
  });

async/await 사용

  • Axios, Fetch 에서 사용 가능.
  • 간결하고, 동기적인 코드 스타일로 작성 가능.
  • 가독성 향상과 오류 처리의 직관성.
async function postData() {
  try {
    const response = await axios.post('API URL', {
      title: 'New Post',
      content: 'This is a new post content.',
    });
    console.log(response.data);
  } catch (error) {
    console.error(error);
  }
}
postData();

요청 쉬소 토큰

  • HTTP 요청 취소를 간편하게 처리.
  • catch 문 안에서 axios.isCancel()을 통해 취소 인지 가능.
// 취소 토큰 생성
const source = axios.CancelToken.source();
// POST 요청 보내기
axios
  .post(
    'API URL',
    {
      title: 'New Post',
      content: 'This is a new post content.',
    },
    { cancelToken: source.token }
  )
  .then((response) => {
    console.log(response.data);
  })
  .catch((error) => {
    if (axios.isCancel(error)) {
      console.log('요청이 취소되었습니다:', error.message);
    } else {
      console.error(error);
    }
  });
// 요청 취소
source.cancel('사용자가 요청을 취소함');

TimeOut 설정

  • Axios의 타임아웃은 연결 시간 초과, 응답 시간 초과 에서 적용됨.
  • 타임아웃 시간을 초과하면 요청을 취소함.
  • error.code === 'ECONNABORTED' 로 설정.
axios
  .post(
    'API URL',
    {
      title: 'New Post',
      content: 'This is a new post content.',
    },
    { timeout: 5000 }
  ) // 5초 타임아웃
  .then((response) => {
    console.log(response.data);
  })
  .catch((error) => {
    if (error.code === 'ECONNABORTED') {
      console.log('요청이 타임아웃되었습니다:', error.message);
    } else {
      console.error(error);
    }
  });

0개의 댓글