091
[JS/TS] 프론트엔드와 서버의 통신: AJAX, Fetch API, Axios 본문
[JS/TS] 프론트엔드와 서버의 통신: AJAX, Fetch API, Axios
공구일 2026. 3. 16. 20:581. 프론트엔드와 서버 통신
(0) HTML <form>은 페이지 전체 새로고침을 해야합니다.
<form action="/users" method="GET">
<button>조회</button>
</form>
(1) AJAX(Asynchronous JavaScript and XML)은 HTML <form> 태그를 통한 동기식 요청을 사용하지 않고 페이지 전체를 새로고침하지 않아도 화면의 특정 부분만 동적으로 갱신할 수 있는 기술입니다. 초기에는 XMLHttpRequest(XHR) 객체를 사용했지만, 콜백 함수(어떤 작업이 끝난 후에 실행되도록 다른 함수에 전달되는 함수) 기반으로 설계되어있던 XHR은 비동기 처리가 복잡해질수록 콜백 지옥(코드가 계속 중첩됨)을 유발했으며, API 설계가 직관적이지 않았습니다. 그리하여 JSON 포맷이 API 통신의 절대적인 표준이 되었습니다.
- XHR
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/users");
xhr.onload = function () {
if (xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log(data);
}
};
xhr.onerror = function () {
console.log("request error");
};
xhr.send();
(2) Fetch API는 XHR의 구조적 단점을 극복하기 위해 도입된 JS 내장 표준 API로, 콜백 함수 대신 Promise 객체를 반환하므로 비동기 코드를 훨씬 간결하게 작성할 수 있으며, async/await 문법과 결합하여 동기식 코드처럼 직관적 흐름 제어가 가능합니다.
- Promise 객체는 미래에 완료될 작업의 결과를 담는 객체로, DB 조회나 파일 읽기 등의 시간이 걸리는 작업을 위해 비동기 처리가 필요할 때 사용합니다. Promise는 Pending(작업 진행중), Fulfilled(성공), Rejected(실패)의 총 3가지 상태가 있습니다.
const promise = new Promise((resolve, reject) => {
});
-> 이런 구조로 선언되며 성공 시에는 resolve, 실패 시에는 reject에 해당하는 값이 출력됩니다.(아래 예시 참조)
function getData() {
return new Promise((resolve, reject) => {
const success = false;
setTimeout(() => {
if(success){
resolve("데이터 성공");
}else{
reject("데이터 실패");
}
},1000);
});
}
getData()
.then((data)=>{ console.log(data); })
.catch((error)=>{ console.log(error); });
- 실제로 Promise 객체를 반환하는 API를 사용하다보면 Promise 체이닝 때문에 가독성이나 유지보지수에서 문제를 가지게 됩니다. 그 문제를 해결하기 위해서 async/await 문법을 사용합니다.
//[1] Fetch API
fetch("/api/users")
.then((response)=>{ return response.json(); })
.then((data)=>{ console.log(data); })
.catch((error)=>{ console.log(error); });
//[2] Fetch API + async/await
async function load(){
try{
const res = await fetch("/api/users");
const data = await res.json();
console.log(data);
}catch(err){
console.log(err);
}
}
-> aysnc/await를 활용해주면 동기 코드처럼 편하게 읽을 수 있다는 장점이 있습니다.
(3) Axios는 내장 Fetch API의 한계점을 해결하기 위해 사용하는 서드파티 라이브러리로, 표준처럼 채택하여 사용됩니다. 아래 코드에서도 확인할 수 있지만 Fetch API는 네트워크나 CORS 에러가 발생했을 때만 reject 하기 때문에 HTTP 에러 상태 코드를 반환하는 경우에는 resolve 됩니다. 직접 반환된 객체인 Response에서 response.ok 속성값을 확인하여 예외처리해줘야합니다. 두 번째 한계점은 반환된 데이터를 자바스크립트 객체로 사용하기 위해서는 response.json() 메서드를 명시적으로 호출하여 비동기 파싱 과정을 거쳐야합니다.
*파싱: 데이터의 포맷을 변환하여 대개 구조적인 데이터를 생성하는 과정을 말합니다.
const fetchMovies = async (): Promise<Movie[]> => {
try {
const response = await fetch('/api/v1/movies');
if (!response.ok) { //[1]HTTP 에러 수동 처리
throw new Error(`HTTP error! status: ${response.status}`);
}
const data: Movie[] = await response.json();//[2] JSON 데이터를 수동으로 파싱
return data;
} catch (error) {
console.error('Failed to fetch movies:', error);
throw error;
}
};
//==============================================================================
const fetchMovies = async (): Promise<Movie[]> => {
try {
const response = await axios.get<Movie[]>('/api/v1/movies', {
timeout: 5000 //[+] 요청 취소 및 타임아웃을 옵션으로 구현
}); //[2]해결: 제네릭을 통해 응답 데이터의 타입을 명시& JSON 데이터 파싱 과정 생략
return response.data;
} catch (error) {
//[1]해결: HTTP 에러 자동 처리!!
console.error('Failed to fetch movies:', error);
throw error;
}
};
(3)-1. Axios Interceptor는 프론트앤드 애플리케이션의 HTTP 통신 과정에서 발생하는 횡당 관심사를 중앙 집중하기 위한 핵심 미들웨어 아키텍처입니다. 인증 토큰의 관리와 인가 처리에서 편리성을 제공합니다.
'Programming Language > JavaScript&TypeScript' 카테고리의 다른 글
| [JS/React] 기초 문법 복습(2): 분할대입, 디폴트 값, 스프레드, 모듈/번들러 (0) | 2026.04.07 |
|---|---|
| [JS/React] 기초 문법 복습(1): const/let, 템플릿 문자열, 화살표 함수 (0) | 2026.04.07 |
| [JavaScript] 객체(미완글) (3) | 2024.11.25 |
| [JavaScript] DOM(미완글) (1) | 2024.11.25 |
| [JavaScript] 함수 및 출력함수 (3) | 2024.11.13 |
