자바스크립트를 사용하여 AJAX 비동기 통신을 위해 별도의 라이브러리를 많이 사용하고 있습니다. 예를들면  jQuery의 ajax() 메소드를 사용하거나 아니면  axios 라이브러리 등을 단지 AJAX 구현을 위한 목적으로 추가해 사용해왔습니다.

왜냐하면 순수 자바스크립트 및 기존 비동기 통신이 어렵고 비효율적이기 때문입니다. 특히 XMLHttpRequest를 사용해서는 원하는 기능을 모두 구현하기 위해서는 매우 복잡하고 Promise 객체를 함께 사용하는 것도 쉽지 않았기 때문이죠.


! ES 6의 fetch API를 알아보자
자바스크립트의 ES 6가 점점 표준이 되면서 fetch API를 사용하는 경우도 점점 많아졌습니다. fetch API는 ES 6의 비동기 통신 방법으로 자체로 Promise 객체를 반환하기에 함께 사용하기도 편리합니다. 아래는 fetch API를 사용하여 서버와 비동기 통신을 어떻게 할 수 있는지 그 방법과 예제에 대하여 자세히 알아봅니다.

@ 장점
- 사용이 쉽고 간단함
- Promise 객체로 값을 Return 받음
- Response 타입별로 쉽게 적용 가능(JSON, Blob 등등)

그럼 아래에서 어떻게 사용하는지 알아보도록 하죠.



# Fetch API 사용하는 간단한 방법
먼저 Fetch API의 코드는 아래와 같은 형태를 가지고 있습니다.
fetch(url).then(function(response) {
  // Code ...
}).catch(function(error) {
  // Error
  console.log(error);
});;

위 예제에서 통신에 성공할 경우 then()을 사용하여 콜백함수를 실행합니다. 위에서 catch()의 경우 에러가 발생했을 때의 핸들링을 여기서 처리하도록 합니다.

! Fetch API 통신 실패

즉 catch()는 정상 통신 실패하여 에러가 발생되었을 때 어떻게 처리할 것인지를 수행하는 메소드입니다. 콘솔로 에러를 출력하거나 토스트 등의 메시지를 보내서 처리할 수 있습니다.

여기까지 알아보면 Fetch API 역시 보시는 것처럼 코드는 간단합니다. ajax, axois 등의 다른 라이브러리 등과 모습, 문법도 비슷하죠. 그래서 더 쉽게 접근이 가능합니다. 아래는 간단한 옵션을 사용하였을 때의 예제입니다.
fetch(url, {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  }
}).then(function(response) {
  // Code ...
});

위에서는 사용할 메소드(method)와 헤더값으로 콘텐츠 타입을 지정하였습니다. 서버에 Request 값을 설정하는 방법을 자세히 알아보겠습니다. 아래와 같이 많은 값들을 설정할 수 있습니다.

! Request 설정 옵션
method // 사용할 메소드를 선택 (GET, POST, PUT, DELETE 등등)
headers // 헤더에 전달할 값
body // 바디에 전달할 값
mode  //  cors 등의 값을 설정 (cors, no-cors, same-origin)
cache  //  캐쉬 사용 여부 (no-cache, reload, force-cache, only-if-cached)
credentials  //  자격 증명을 위한 옵션 설정(include, same-origin, omit) (Default. same-origin)

일반적으로 설정값들만 따로 모아 하나의 객체 변수에 저장하여 많이 사용합니다.
let optObj = {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  },
  'mode': 'cors'
};
fetch(url, optObj).then(function() {
  ...
});

그럼 아래부터는 간단한 예제들을 알아봅니다.


! Fetch() POST, PUT, DELETE 메소드 예제 보기
get이 아닌 다른 메소드를 사용하는 경우에는 다음과 같이 method 값을 post 등으로 바꾸어 사용할 수 있습니다. 만약 POST 메소드라면 아래와 같이 작성합니다.
fetch(url, {
  method: 'POST'
}).then(function(response) {
  ...
});

데이터를 전송하는 경우에는 다음처럼 body에 값을 추가합니다. 아래는 sitename으로 'webisfree'라는 값을 서버에 전달합니다. body는 JSON.stringify()를 사용하여 문자열로 변환하여 전달합니다.
JSON.stringify({ sitename: 'webisfree' })

이제 body값을 추가하여 코드를 아래와 같이 작성합니다.
fetch(url, {
  method: 'POST',
  body: JSON.stringify({ sitename: 'webisfree' })
}).then(function(response) {
  ...
});

이처럼 body에 JSON.stringify()를 사용하지 않으면 에러가 발생할 수 있습니다. 일부 라이브러리는 자동으로 변환해주기도 하지만 Fetch API에서는 직접 JSON.stringify()를 사용하여 JSON 타입의 문자열로 변환해야 합니다.




# Request, Response, Headers 인터페이스 지원fetch API는 Request, Response, Headers라는 인터페이스를 지원합니다. 이를 사용하면 HTTP 요청시 더 쉽고 간단하고 값을 설정하고 전달 할 수 있습니다.

@ Headers()
헤더 정보에 포함되는 값들을 설정합니다.
var _header = new Headers();
_header.append('Content-Type', 'application/json');

append()나 set()을 사용하여 값을 설정할 수 있고 get()으로 값을 가져오거나 delete()로 삭제하는 방법이 매우 간단합니다.
_header.get('Content-Type'); // 'application/json' 값 출력


_header.delete('Content-Type');
_header.get('Content-Type'); // 삭제되어 null을 출력함

@ Request()
서버에 요청할 때의 값으로 URL, Body값 등을 설정하여 전달할 수 있습니다.


! 브라우저 호환성
fetch API는 대부분의 최신 브라우저에서는 정상 동작하나 ES 6를 완벽하게 지원하지 않는 IE(익스플러러) 등에서는 fetch API가 동작하지 않을 수 있습니다. 지원되는 브라우저라면 fetch()를 비롯하여 Request, Response, Headers 등의 API가 사용 가능합니다.

IE를 지원하기 위해서 사용 가능하도록 Fetch API를 지원 가능하도록 변환하는 npm 등의 패키지를 설치할 수도 있고 아니면 fetch가 아닌 axios 등의 라이브러리를 사용하는 것이 가장 간단하고 빠른 해결책입니다.