JavaScript
AJAX와 Fetch의 성공·실패 경계
페이지 전체를 새로고침하지 않고 서버와 비동기로 데이터를 주고받으며, 네트워크 연결 실패와 HTTP 상태 오류를 구분해 처리합니다.
이럴 때 필요해요
404·500 응답을 성공으로 잘못 처리하거나 화면 전환 후 뒤늦게 도착한 응답이 최신 화면을 덮어쓰는 문제를 막을 수 있습니다.
어떻게 동작하나요?
웹페이지에서 검색어를 입력하거나 좋아요 버튼을 눌렀을 때 화면 전체가 깜빡이며 새로고침되지 않고 필요한 부분만 자연스럽게 바뀌는 것은 브라우저가 배경에서 서버와 데이터를 주고받기 때문입니다. 이처럼 페이지 전체 이동 없이 비동기적으로 서버와 통신해 UI를 갱신하는 기법을 AJAX라고 부릅니다. 이름에 XML이 들어가 있지만 오늘날에는 주로 JSON 형식을 주고받으며, 과거의 XMLHttpRequest 대신 Promise 기반의 Fetch API를 표준으로 사용합니다.
Fetch를 사용할 때 가장 주의할 점은 '어디까지를 에러로 보는가'입니다. fetch()가 반환하는 Promise는 인터넷 연결이 끊기거나 CORS 정책에 막히는 등 네트워크 통신 자체가 실패했을 때만 거부(reject)됩니다. 서버가 404(Not Found)나 500(Server Error) 상태 코드를 돌려주더라도 응답 자체는 도착했으므로 Promise는 정상 이행(fulfill)됩니다. 따라서 반드시 response.ok나 response.status를 직접 확인해 HTTP 오류를 분기하고, 응답 본문을 읽는 response.json() 역시 별도의 비동기 단계라는 점을 고려해야 합니다.
사용자가 탭을 빠르게 바꾸거나 페이지를 떠나면 이전 요청의 응답이 뒤늦게 도착해 최신 화면 상태를 덮어쓰는 경쟁 상태(Race Condition)가 생길 수 있습니다. 이를 막으려면 AbortController로 생성한 signal을 fetch에 전달해 필요 없어진 요청을 취소해야 합니다. 다만 클라이언트에서 요청을 abort하더라도 서버가 이미 처리하기 시작한 작업이 자동으로 롤백되지는 않으므로, 재시도나 취소 설계 시 서버 API의 멱등성(Idempotency)도 함께 확인합니다.
코드 예제
동작을 설명하는 읽기 전용 예제입니다.
async function load(url, signal) {
const response = await fetch(url, { signal });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}브라우저 환경에서 AbortSignal을 함께 전달하고, 본문(JSON)을 파싱하기 전에 response.ok로 HTTP 상태 코드를 먼저 검사하는 패턴입니다.
이 개념으로 실습하기
자주 헷갈리는 포인트
- fetch의 Promise가 이행(resolve)되었다는 사실만으로 서버 비즈니스 요청이 성공했다고 단정하지 않습니다.
- 클라이언트에서 요청을 abort하는 것이 서버 데이터베이스의 트랜잭션을 자동으로 되돌려 준다고 오해하지 않습니다.
내 말로 설명해 보기
서버의 404 응답과 사용자의 인터넷 연결 단절은 코드에서 각각 어떤 경로로 구분해 처리해야 할까요?
실전 시나리오에 적용해 보기
함께 읽으면 좋은 개념
관련 면접 질문 1개
AJAX는 무엇이며 Fetch로 구현할 때 무엇을 확인해야 하나요?
AJAX는 페이지 전체를 새로고침하지 않고 브라우저가 서버와 비동기적으로 데이터를 주고받아 화면 일부만 갱신하는 기법입니다. 현대 웹에서는 주로 Fetch API와 JSON 형식을 사용해 구현합니다. Fetch를 사용할 때는 네트워크 연결 실패뿐 아니라 404나 500 같은 HTTP 상태 코드를 확인하기 위해 response.ok나 status를 직접 검사해야 하며, 응답 본문을 읽는 response.json() 역시 비동기 단계라는 점과 화면 이탈 시 요청 취소(AbortController)까지 함께 챙겨야 합니다.
꼬리질문과 참고자료 →