웹사이트 검색

Fetch API 입문서


Fetch는 XMLHttpRequest와 관련된 번거로움 없이 Ajax 요청을 수행할 수 있는 새로운 약속 기반 API입니다. 이 게시물에서 볼 수 있듯이 Fetch는 사용 및 작업이 매우 쉽고 API에서 리소스 가져오기를 크게 단순화합니다. 또한 이제 모든 최신 브라우저에서 지원되므로 Fetch를 사용하는 것은 정말 쉬운 일입니다.

요청 받기

JSONPlaceholder API에서 더미 데이터를 GET하여 간단한 GET 요청을 시연해 보겠습니다.

fetch('https://jsonplaceholder.typicode.com/users')
  .then(res => res.json())
  .then(res => res.map(user => user.username))
  .then(userNames => console.log(userNames));

출력은 다음과 같은 사용자 이름의 배열입니다.

["Bret", "Antonette", "Samantha", "Karianne", "Kamren", "Leopoldo_Corkery", "Elwyn.Skiles", "Maxime_Nienow", "Delphine", "Moriah.Stanton"]

JSON 응답이 예상되는 경우 먼저 json() 메서드를 호출하여 Response 개체를 상호 작용할 수 있는 개체로 변환해야 합니다. 대신 XML 응답이 예상되는 경우 text()를 사용할 수 있습니다.

게시, 넣기 및 삭제 요청

GET 이외의 요청을 하려면 사용할 메서드와 필요한 헤더 및 요청 본문을 사용하여 객체를 가져오기 호출에 대한 두 번째 인수로 전달합니다.

const myPost = {
  title: 'A post about true facts',
  body: '42',
  userId: 2
}

const options = {
  method: 'POST',
  body: JSON.stringify(myPost),
  headers: {
    'Content-Type': 'application/json'
  }
};

fetch('https://jsonplaceholder.typicode.com/posts', options)
  .then(res => res.json())
  .then(res => console.log(res));

JSONPlaceholder는 ID가 첨부된 POST 데이터를 다시 전송합니다.

Object {
  body: 42,
  id: 101,
  title: "A post about true facts",
  userId: 2
}

요청 본문을 문자열화해야 한다는 점을 알 수 있습니다. 가져오기 호출에 사용할 수 있는 다른 메서드는 DELETE, PUT, HEADOPTIONS입니다.

오류 처리

Fetch API를 사용한 오류 처리와 관련하여 캐치(말장난 😉)가 있습니다. 요청이 엔드포인트에 제대로 도달하고 반환되면 오류가 발생하지 않습니다. 이는 오류 처리가 가져오기 약속 체인의 끝에서 catch 호출을 연결하는 것처럼 간단하지 않다는 것을 의미합니다.

다행히 가져오기 호출의 응답 개체에는 요청의 성공 여부에 따라 true 또는 false가 되는 ok 속성이 있습니다. 그런 다음 ok가 false인 경우 Promise.reject()를 사용할 수 있습니다.

fetch('https://jsonplaceholder.typicode.com/postsZZZ', options)
  .then(res => {
    if (res.ok) {
      return res.json();
    } else {
      return Promise.reject({ status: res.status, statusText: res.statusText });
    }
  })
  .then(res => console.log(res))
  .catch(err => console.log('Error, with message:', err.statusText));

위의 예에서는 존재하지 않는 끝점을 호출하기 때문에 약속이 거부됩니다. 연결된 catch 호출이 적중되고 다음이 출력됩니다.

"Error, with message: Not Found"

가져오기 + 비동기/대기

Fetch는 약속 기반 API이므로 async 함수를 사용하면 코드를 훨씬 더 쉽게 추론하고 동기식으로 보이게 할 수 있습니다. 예를 들어 간단한 GET 요청을 수행하고 반환된 JSON 응답에서 사용자 이름을 추출한 다음 콘솔에 결과를 기록하는 async/await 함수가 있습니다.

async function fetchUsers(endpoint) {
  const res = await fetch(endpoint);
  let data = await res.json();

  data = data.map(user => user.username);

  console.log(data);
}

fetchUsers('https://jsonplaceholder.typicode.com/users');

또는 async/await 함수에서 약속을 반환한 다음 함수를 호출한 후 then 호출을 계속 연결할 수 있습니다.

async function fetchUsers(endpoint) {
  const res = await fetch(endpoint);
  const data = await res.json();

  return data;
}

fetchUsers('https://jsonplaceholder.typicode.com/users')
  .then(data => {
    console.log(data.map(user => user.username));
  });

json()을 호출하면 약속이 반환되므로 위의 예에서 비동기 함수에서 데이터를 반환할 때 약속을 반환합니다.

그리고 다시 응답의 ok가 거짓이면 오류를 발생시키고 약속 체인에서 평소와 같이 오류를 잡을 수 있습니다.

async function fetchUsers(endpoint) {
  const res = await fetch(endpoint);

  if (!res.ok) {
    throw new Error(res.status); // 404
  }

  const data = await res.json();
  return data;
}

fetchUsers('https://jsonplaceholder.typicode.com/usersZZZ')
  .then(data => {
    console.log(data.map(user => user.website));
  })
  .catch(err => console.log('Ooops, error', err.message));
Ooops, error 404

폴리필

  • Internet Explorer 11과 같은 이전 브라우저를 지원해야 하는 경우 Github에서 이와 같은 Fetch polyfill을 사용해야 합니다.
  • Node.js에서 Fetch를 사용해야 하는 경우 가장 널리 사용되는 두 가지 옵션은 node-fetch입니다.

브라우저 지원

caniuse.com.