JavaScript Fetch API 완전 가이드: 기본, 예제, 오류 처리 및 보안

目次

1. Introduction: What Is the Fetch API?

JavaScript는 웹 애플리케이션 프런트엔드 개발에서 중요한 역할을 합니다. 그 중 Fetch API는 서버와의 비동기 통신을 수행하는 강력한 도구입니다. 이 글에서는 초보자도 이해하기 쉽게 Fetch API 사용법을 설명하고, 실용적인 예제를 통해 기능을 소개합니다.

What Is the Role of the Fetch API?

Fetch API는 HTTP 요청 및 응답을 처리하기 위한 최신 표준 인터페이스입니다. 과거에는 XMLHttpRequest가 일반적으로 사용되었지만, Fetch API는 더 간단하고 직관적인 설계를 제공합니다.

Differences Between Fetch API and XMLHttpRequest

Fetch API와 기존 XMLHttpRequest의 주요 차이점은 다음과 같습니다.

FeatureFetch APIXMLHttpRequest
Code readabilitySimple and intuitiveCallbacks often become complex
Promise supportBuilt-in Promise supportNo native Promise support
Error handlingClearly distinguishes HTTP status and network errorsError handling is more complex
ExtensibilityEasy to configure abort and timeoutRequires additional code

위와 같이 Fetch API는 현대 웹 개발에서 보다 유연하고 개발자 친화적인 도구로 널리 사용됩니다.

Common Use Cases for the Fetch API

Fetch API는 다음과 같은 상황에서 흔히 사용됩니다.

  1. 데이터 조회: API에서 사용자 정보나 게시물 데이터를 가져오기.
  2. 데이터 전송: 폼 데이터나 JSON 데이터를 서버에 전송하기.
  3. 실시간 업데이트: 서버에서 동적 데이터를 받아와 페이지 내용을 업데이트하기.
  4. 외부 API 연동: 서드파티 API와 연결해 기능을 확장하기.

이러한 이유로 Fetch API는 현대 JavaScript 개발에서 필수적인 요소가 되었습니다.

Summary

이 섹션에서는 Fetch API의 기본 역할과 장점을 설명했습니다. 기존 XMLHttpRequest에 비해 Fetch API는 더 직관적이고 사용이 쉬우며, Promise 기반이라 오류 처리가 간단합니다. 다음 섹션에서는 구체적인 코드 예제를 통해 Fetch API의 기본 사용법을 살펴보겠습니다.

계속 진행하면 Fetch API를 활용해 데이터를 가져오고 조작하는 방법을 실제로 배울 수 있습니다.

2. Basic Usage of the Fetch API (With Sample Code)

이 섹션에서는 Fetch API의 기본 사용법을 구체적인 코드 예제로 설명합니다. 초보자도 따라 할 수 있도록 간단한 GET 요청부터 시작합니다.

Basic Fetch API Syntax

Fetch API의 기본 문법은 아래와 같습니다.

fetch(url, options)
  .then(response => {
    // Handle the response
  })
  .catch(error => {
    // Handle errors
  });
  • url: 요청 URL을 지정합니다.
  • options: HTTP 메서드와 헤더 등을 설정하는 옵션 객체(선택 사항)입니다.
  • then: 응답을 처리합니다.
  • catch: 오류를 처리합니다.

Example of a GET Request

아래는 GET 요청의 기본 예시입니다.

fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => {
    if (!response.ok) {
      throw new Error('A network error occurred');
    }
    return response.json();
  })
  .then(data => {
    console.log(data); // Display data
  })
  .catch(error => {
    console.error('Error:', error);
  });

Using async/await

현대 JavaScript에서는 async/await를 사용해 코드를 더 깔끔하게 작성할 수 있습니다.

async function fetchPost() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
    if (!response.ok) {
      throw new Error('A network error occurred');
    }
    const data = await response.json();
    console.log(data); // Display data
  } catch (error) {
    console.error('Error:', error);
  }
}

fetchPost();

Adding URL Parameters

쿼리 파라미터를 포함하려면 요청을 다음과 같이 작성합니다.

const userId = 1;
fetch(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`)
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Summary

이 섹션에서는 Fetch API를 이용한 GET 요청의 기본 사항을 다루었습니다.

  • 기본 구문: 간단하고 이해하기 쉬운 설계.
  • 오류 처리: 네트워크 및 HTTP 오류를 모두 지원합니다.
  • async/await: 가독성과 유지보수성을 향상시킵니다.
  • URL 매개변수: 동적 조건을 쉽게 구현할 수 있습니다.

다음 섹션에서는 Fetch API가 반환하는 응답 데이터를 보다 자세히 처리하는 방법을 설명합니다.

3. 응답 처리 및 데이터 형식 변환

이 섹션에서는 Fetch API를 사용하여 가져온 응답을 처리하는 방법을 설명합니다. 특히 JSON 데이터 변환과 텍스트 및 바이너리 데이터 작업에 중점을 둡니다.

Fetch API 응답 객체란 무엇인가요?

Fetch API를 사용하면 요청 후 반환되는 응답이 Response 객체로 제공됩니다.

주요 속성

PropertyDescription
okA boolean value indicating whether the response was successful (HTTP status 200–299).
statusThe HTTP status code (e.g., 200, 404, 500).
statusTextA description of the HTTP status (e.g., OK, Not Found).
headersResponse header information.

JSON 데이터 가져오기 및 변환

Fetch API를 사용할 때 서버는 종종 JSON 형식으로 데이터를 반환합니다.

fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => {
    if (!response.ok) {
      throw new Error('Response error: ' + response.status);
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

텍스트 데이터 가져오기

경우에 따라 JSON 대신 일반 텍스트 형태로 데이터를 가져와야 할 수도 있습니다.

fetch('https://example.com/textfile.txt')
  .then(response => response.text())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

바이너리 데이터 가져오기

이미지나 파일을 바이너리 데이터로 가져오려면 blob() 또는 arrayBuffer()를 사용합니다.

fetch('https://example.com/image.jpg')
  .then(response => response.blob())
  .then(blob => {
    const url = URL.createObjectURL(blob);
    document.getElementById('image').src = url;
  })
  .catch(error => console.error('Error:', error));

요약

이 섹션에서는 Fetch API 응답을 처리하고 데이터 형식을 변환하는 방법을 배웠습니다.

  • JSON 데이터: 가장 일반적인 서버 응답 형식을 지원합니다.
  • 텍스트 및 바이너리 데이터: 필요에 따라 다양한 형식을 가져올 수 있습니다.
  • 응답 헤더: 데이터 관리 및 보안 검증에 유용합니다.

4. POST 요청 전송 (실용 예제 포함)

이 섹션에서는 Fetch API를 사용한 POST 요청으로 서버에 데이터를 전송하는 방법을 설명합니다. 실용적인 예제를 통해 폼 데이터와 JSON 데이터를 전송하는 방법을 다룹니다.

POST 요청의 기본 구문

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})
  • method: 사용할 HTTP 메서드를 지정합니다(이 경우 POST).
  • headers: 데이터 형식을 지정합니다(예: JSON 또는 폼 데이터).
  • body: 데이터를 문자열로 변환하여 전송합니다.

예시: JSON 데이터 전송

const userData = {
  name: 'Taro Tanaka',
  email: 'taro.tanaka@example.com'
};

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(userData)
})
  .then(response => response.json())
  .then(data => console.log('Success:', data))
  .catch(error => console.error('Error:', error));

예시: 폼 데이터 전송

const formData = new FormData();
formData.append('name', 'Taro Tanaka');
formData.append('email', 'taro.tanaka@example.com');

fetch('https://example.com/api/submit', {
  method: 'POST',
  body: formData
})
  .then(response => response.text())
  .then(data => console.log('Success:', data))
  .catch(error => console.error('Error:', error));

예시: 인증이 포함된 요청

fetch('https://example.com/api/protected', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  },
  body: JSON.stringify({ query: 'data' })
})
  .then(response => response.json())
  .then(data => console.log('Success:', data))
  .catch(error => console.error('Error:', error));

요약

이 섹션에서 우리는 Fetch API를 사용한 POST 요청의 기본 사항과 실용적인 사용법을 다루었습니다.

  • JSON 데이터 전송: API 통합에 이상적입니다.
  • 폼 데이터 전송: 간단한 폼과 파일 업로드에 잘 작동합니다.
  • 인증된 요청: API 보안 요구 사항을 지원합니다.

다음 섹션에서는 Fetch API의 오류 처리와 디버깅 기법에 대해 더 깊이 파고듭니다.

5. 오류 처리와 디버깅 기법

이 섹션에서 우리는 Fetch API를 사용할 때의 오류 처리와 디버깅 기법을 자세히 살펴봅니다.

Fetch API에서 발생하는 일반적인 오류

Error TypeCause
Network errorConnection failure to the server, offline state, or request timeout.
HTTP errorHTTP status codes of 400 or higher (e.g., 404, 500).
Data format errorThe response data is not returned in the expected format.
Syntax error (SyntaxError)Invalid JSON data or string parsing errors.
Authentication / authorization errorMissing tokens, invalid credentials, or insufficient access permissions.

기본 오류 처리

fetch('https://jsonplaceholder.typicode.com/posts/9999')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }
    return response.json();
  })
  .catch(error => console.error('Error:', error.message));

타임아웃 처리

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

const timeout = setTimeout(() => controller.abort(), 5000);

fetch('https://jsonplaceholder.typicode.com/posts', { signal })
  .then(response => response.json())
  .catch(error => {
    if (error.name === 'AbortError') {
      console.error('Timeout: The request was aborted');
    } else {
      console.error('Error:', error.message);
    }
  })
  .finally(() => clearTimeout(timeout));

디버깅 기법

  1. 로그 출력:
    fetch('https://example.com/api/data')
      .then(response => {
        console.log('Status code:', response.status);
        return response.json();
      })
      .then(data => console.log('Data:', data))
      .catch(error => console.error('Error:', error.message));
    
  1. 브라우저 개발자 도구 (Network 탭):
  • 실시간으로 요청과 응답을 검사합니다.

요약

이 섹션에서 우리는 Fetch API의 오류 처리와 디버깅 기법을 탐구했습니다.

  • 일반적인 오류: 네트워크 오류, JSON 파싱 오류, 타임아웃 문제.
  • 상세한 오류 처리: 명확한 오류 처리 로직을 가진 실용적인 예제.
  • 디버깅: 로그와 브라우저 개발자 도구를 사용하여 문제를 식별합니다.

다음 섹션에서는 Fetch API의 고급 사용 패턴과 보안 조치를 설명합니다.

6. 고급 사용법과 보안 조치

이 섹션에서 우리는 Fetch API의 고급 사용 기법과 보안 고려 사항을 설명합니다.

요청 중단 (AbortController)

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

fetch('https://jsonplaceholder.typicode.com/posts', { signal })
  .then(response => response.json())
  .catch(error => {
    if (error.name === 'AbortError') {
      console.error('The request was aborted');
    } else {
      console.error('Error:', error.message);
    }
  });

setTimeout(() => controller.abort(), 3000); // Abort after 3 seconds

인증 자격 증명을 사용한 요청

const token = 'YOUR_ACCESS_TOKEN';

fetch('https://example.com/api/protected', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  }
})
  .then(response => response.json())
  .then(data => console.log('Data:', data))
  .catch(error => console.error('Error:', error));

CORS (Cross-Origin Resource Sharing) 지원

fetch('https://example.com/api/data', {
  method: 'GET',
  mode: 'cors'
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

요약

이 섹션에서 우리는 고급 Fetch API 사용법과 보안 조치를 다루었습니다.

  • 요청 중단: AbortController를 사용하여 효율성을 향상시킵니다.
  • 인증된 요청: API 토큰과 CSRF 대책을 구현합니다.
  • CORS 처리: 적절한 구성으로 교차 출처 문제를 해결합니다.

7. 일반적인 오류와 문제 해결 (요약 테이블 포함)

이 섹션에서는 Fetch API를 사용할 때 발생할 수 있는 일반적인 오류와 이를 해결하는 방법을 설명합니다.

일반적인 오류와 그 원인

Error Code / MessageCauseSolution
TypeError: Failed to fetchNetwork issues, incorrect URL, server downtime, or CORS configuration errors.Verify the URL, check network connectivity, and review CORS settings.
SyntaxError: Unexpected token <Invalid JSON format or receiving HTML instead of JSON.Inspect the response as text and verify the returned data format.
404 Not FoundThe specified resource does not exist on the server.Check the URL path and confirm dynamic parameter handling.
500 Internal Server ErrorAn internal server-side error.Review server logs to identify the root cause.

상세한 오류 처리

fetch('https://invalid-url.example.com')
  .then(response => response.json())
  .catch(error => {
    if (error.message.includes('Failed to fetch')) {
      console.error('Network error');
    } else {
      console.error('Other error:', error.message);
    }
  });

요약

이 섹션에서는 Fetch API의 일반적인 오류와 이를 처리하는 방법을 검토했습니다.

  • 일반적인 오류: 네트워크 오류, JSON 형식 오류, 그리고 타임아웃 문제.
  • 상세한 처리: 견고한 오류 처리를 보여주는 실용적인 예제.

8. 실용적인 예제: API 데이터를 사용한 간단한 웹 앱 구축

이 섹션에서는 Fetch API를 사용하여 외부 API에서 데이터를 가져오는 간단한 웹 애플리케이션을 만드는 방법을 설명합니다.

HTML 준비

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Fetch API Sample App</title>
</head>
<body>
  <h1>Post List</h1>
  <button id="fetchButton">Fetch Data</button>
  <ul id="postList"></ul>
  <p id="errorMessage" style="color: red;"></p>

  <script src="app.js"></script>
</body>
</html>

JavaScript 코드 생성

const fetchButton = document.getElementById('fetchButton');
const postList = document.getElementById('postList');
const errorMessage = document.getElementById('errorMessage');

async function fetchPosts() {
  fetchButton.disabled = true;
  errorMessage.textContent = '';
  postList.innerHTML = '';

  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }
    const posts = await response.json();
    posts.forEach(post => {
      const listItem = document.createElement('li');
      listItem.textContent = `${post.id}: ${post.title}`;
      postList.appendChild(listItem);
    });
  } catch (error) {
    errorMessage.textContent = 'Failed to retrieve data.';
  } finally {
    fetchButton.disabled = false;
  }
}

fetchButton.addEventListener('click', fetchPosts);

요약

이 섹션에서는 Fetch API를 사용하여 실용적인 웹 애플리케이션을 구축하는 방법을 보여주었습니다.

  • 핵심 기능: 데이터 검색 및 목록 렌더링.
  • 오류 처리: 실패 시 사용자 친화적인 메시지 표시.

9. 결론 및 다음 단계

이 기사에서는 Fetch API를 기본부터 고급 사용법과 실용적인 예제까지 포괄적으로 다루었습니다. 이 마지막 섹션에서는 각 섹션의 주요 포인트를 검토하고 다음에 배울 것을 제안합니다.

주요 요점

Fetch API의 기본 구조와 기능

  • Fetch API는 JavaScript에서 서버와 비동기 통신을 수행하기 위한 강력한 인터페이스입니다.
  • 전통적인 XMLHttpRequest에 비해 더 간단하고, 유연하며, Promise 기반으로 가독성을 크게 향상시킵니다.

데이터 검색 및 응답 처리

  • JSON, 텍스트, 바이너리 데이터를 검색하는 방법을 설명했습니다.
  • async/await를 사용하면 더 직관적인 코드와 간단한 오류 처리를 작성할 수 있습니다.

데이터 제출 및 POST 요청

  • 서버에 JSON 데이터와 폼 데이터를 보내는 방법을 배웠습니다.
  • 인증 토큰을 사용한 보안 요청도 다루었습니다.

오류 처리 및 디버깅 기법

  • 네트워크 오류와 JSON 파싱 오류에 대한 실용적인 해결책을 소개했습니다.
  • 요청 타임아웃과 요청 중단과 같은 고급 기법을 구현했습니다.

실용적인 웹 애플리케이션 구축

  • 외부 API에서 데이터를 가져와 UI에 동적으로 표시하는 웹 애플리케이션을 구축했습니다.
  • 오류 처리와 버튼 상태 제어를 통해 실제 개발 시나리오를 반영하는 디자인 패턴을 배웠습니다.

다음 단계

To make even better use of the Fetch API, consider learning the following topics.

고급 API 구현 기술

  • 페이징과 정렬: 대규모 데이터셋을 다룰 때 처리 최적화.
  • 검색 기능: 사용자 입력에 기반한 데이터 필터링 구현.
  • 파일 업로드: 이미지와 비디오 업로드 처리.

보안 강화

  • OAuth 2.0 및 인증: 보안 API 연결을 위한 인증 및 권한 부여 프로세스 이해.
  • CSRF 및 XSS 보호: 더 안전한 폼 제출 구현 및 악성 스크립트로부터 방어.

현대 기술과의 통합

  • Axios 라이브러리: HTTP 요청 관리를 단순화하는 Fetch API의 인기 있는 대안.
  • GraphQL: REST API에 비해 데이터 검색을 최적화하는 현대적인 API 설계 모델.
  • 실시간 통신: WebSocket 또는 Server-Sent Events를 사용한 실시간 데이터 교환 구현.

학습 자료

다음 공식 문서와 학습 자료를 사용하여 기술을 더욱 향상시키세요.

최종 노트

이 기사를 통해 Fetch API의 기본부터 실세계 사용까지 모든 것을 다루는 지식과 실전 기술을 습득했습니다.

Fetch API는 간단한 데이터 검색부터 복잡한 API 통합까지 다양한 작업에 널리 사용됩니다. 여기서 배운 것을 실제 프로젝트에 적용함으로써 더욱 실전적인 경험을 쌓을 수 있습니다.

다음 조치:

  • 실제 API를 사용한 작은 프로젝트를 구축하여 실습 경험을 쌓으세요.
  • 오류 처리와 보안 조치를 강화하여 프로덕션 준비도를 향상시키세요.
  • GraphQL 및 실시간 통신과 같은 새로운 기술을 채택하여 기술 세트를 더욱 확장하세요.
広告