본문 바로가기

CS

[CS] Fetch란?

 

 

Fetch란?

JavaScript에서 네트워크 요청을 보내고 응답을 처리하는 API이다.

최신 웹 애플리케이션에서 비동기적으로 서버와 데이터를 주고받는 데 사용된다.

 


 

Fetch 등장 배경

기존의 XMLHttpRequest (XHR)의 한계를 해결하기 위해서 등장했다.

 

(1) XHR의 단점

  • 콜백 방식이어서 코드가 복잡해짐 (콜백 지옥 문제)
  • 오류 처리가 번거로움
  • 요청 및 응답 데이터를 다루는 방식이 제한적
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data", true);
xhr.onreadystatechange = function () {	// 콜백 함수
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(JSON.parse(xhr.responseText));
  }
};
xhr.send();

위 코드처럼 XHR은 onreadystatechange(XHR 객체의 이벤트 핸들러)를 설정하고 여러 단계를 거쳐야하고, 상태(readyState) 체크도 필요하다. 콜백 함수 안에서 처리해야 해서 코드가 길어지고 복잡하여 가독성에도 좋지 않다.

 

 

(2) Fetch의 장점

  • Promise 기반으로 동작하여 코드가 간결함
  • async/await를 사용할 수 있어 비동기 코드 관리가 쉬움
  • then과 catch를 활용해 에러 처리가 간편
  • 다양한 데이터 포맷(JSON, Blob, FormData 등)을 쉽게 다룰 수 있음
function fetchData() {
  fetch('https://api.example.com/data')
    .then(response => response.json())  // 응답을 JSON으로 변환
    .then(data => console.log(data))    // 데이터 출력
    .catch(error => console.error('Error:', error)); // 에러 처리
}
fetchData();

✅ 위 코드처럼 .then을 사용하면 Promise 체이닝 방식을 통해 Promise를 여러 개 체이닝 해서 순차적으로 실행할 수 있다.

👉 .then()이 여러 번 중첩되고 코드가 길어지면 가독성이 떨어질 수 있다.

 

 

async function fetchData() {
  try {
    // fetch()를 호출하고 서버 응답을 받을 때까지 기다림
    const response = await fetch('https://api.example.com/data');  // 비동기 작업
    
    // 응답(response)의 본문을 JSON 형식으로 변환할 때까지 기다림	
    const data = await response.json();	// 비동기 작업
    
    // 변환된 JSON 데이터 출력
    console.log(data);
  } catch (error) {
    // 네트워크 오류 또는 응답 처리 중 발생한 오류 출력
    console.error('Error:', error);
  }
}

// 함수 실행
fetchData();

✅ 위 코드처럼 async/await을 사용하면 fetch 요청을 동기 코드처럼 작성할 수 있으며, 여러 개의 비동기 작업을 순차적으로 실행할 수 있다.

💡중요 : 위에서 fecth 요청과 같은 비동기 작업은 await 덕분에 동기 실행(처리 될때까지 대기)처럼 보이지만, 실제로는 자바스크립트가 멈춘 것이 아니라 그 줄에서만 대기하고 있고 fetchData() 함수 외 다른 코드가 실행된다. 

(쉽게 말하자면, 동기 실행처럼 보이지만 비동기 실행이라는 것이다.)

✅ 가독성이 더 좋고 직관적이다.

 


 

Fetch의 주요 기능

(1) HTTP 요청 방식 지정

기본적으로 Fetch는 GET 요청을 수행하지만, POST, PUT, DELETE 등 다양한 HTTP 메서드를 사용할 수 있다.

fetch('https://api.example.com/data', {
  method: 'POST', // HTTP 메서드
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'John', age: 30 }) // 전송할 데이터
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

첫번째 파라미터인 URL 다음으로 두 번째 파라미터로 요청에 대한 추가적인 데이터를 입력할 수 있다.

  • method : HTTP method와 동일하며 요청 방식을 나타낸다. (GET, POST, PUT, DELETE 등)
  • headers : 요청 헤더에 대한 정보를 나타낸다. (Content-Type, Authorizaton 등)
  • body : 요청을 보내는 데이터를 나타낸다. 여러 가지 자료형을 대입할 수 있다. (주로 POST, PUT 요청에서 사용)
    • JSON 데이터를 보낼 때는 JSON.stringify()로 변환해야 한다.

 

 

(2) 응답 데이터 처리

Fetch의 응답(Response 객체)은 다음과 같은 데이터를 제공한다.

fetch('https://api.example.com/data')
  .then(response => {
    console.log(response.status); // 상태 코드 (ex: 200, 404)
    console.log(response.ok); // 성공 여부 (true/false)
    return response.text(); // 또는 response.json()
  })
  .then(data => console.log(data));

 

 

(3) 요청 취소하기 (AbortController)

네트워크 요청을 취소하려면 AbortController를 사용할 수 있다.

const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Request aborted:', error));

controller.abort(); // 요청 취소

 


 

Fetch의 한계점과 보완 방법

(1) Fetch는 HTTP 오류 (4xx, 5xx)를 자동으로 감지 ❌ .

  • Fetch는 네트워크 요청 자체가 실패한 경우(offline 상태 등)에만 catch 블록이 실행됨.
  • HTTP 상태 코드 오류(예: 404 Not Found, 500 Internal Server Error)는 자동으로 예외를 발생시키지 않음.
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Fetch error:', error));

!response.ok (응답이 들어오지 않은 경우)에 현재 상태(response.status)가 어떤지 Error 문구를 띄운 것이다.

 

 

(2) Fetch는 타임아웃 기능이 ❌ .

기본적으로 fetch는 요청이 끝날 때까지 기다리므로, 서버가 응답하지 않으면 영원히 대기할 수도 있다.

const controller = new AbortController();
setTimeout(() => controller.abort(), 5000); // 5초 후 요청 취소

fetch('https://api.example.com/data', { signal: controller.signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Request timeout:', error));

setTimeout 함수를 사용하여 특정 시간이 흐른 후에, Fetch가 종료되도록 하였다.

 


 

결론

Fetch는 XMLHttpRequest의 단점을 해결하고, 비동기 네트워크 요청을 더욱 직관적이고 효율적으로 수행할 수 있도록 설계된 최신 웹 API이다.
현재 대부분의 브라우저에서 지원되며, async/await과 함께 사용하면 매우 깔끔한 비동기 코드를 작성할 수 있다.