fetch API는 XMLHTTPRequest에 대한 편의성을 증대하기 위해 ES6+에 추가되었습니다. 기존 XMLHTTPRequest은 사용성이 까다로워 jQuery.ajax 혹은 axios 라이브러리를 많이 사용해왔는데요. 이제는 라이브러리나 플러그인을 설치하는 번거로움없이 브라우저 네이티브로 제공되는 fetch API의 강력하고 유연한 사용성으로 네트워크 통신을 할 수 있습니다.
주의점
- 브라우저 호환성: Chrome 이외는 브라우저는 버전이 낮을 경우 polyfill을 적용하여 fetchAPI를 사용하여야합니다.
- fetch()로 부터 반환되는 Promise 객체는 HTTP error 상태를 reject하지 않습니다. HTTP Statue Code가 404나 500을 반환하더라도요. 대신 ok 상태가 false인 resolve가 반환되며, 네트워크 장애나 요청이 완료되지 못한 상태에는 reject가 반환됩니다.
- 보통 fetch는 쿠키를 보내거나 받지 않습니다. 사이트에서 사용자 세션을 유지 관리해야하는 경우 인증되지 않는 요청이 발생합니다. 쿠키를 전송하기 위해서는 자격증명(credentials) 옵션을 반드시 설정해야 합니다.
2017년 8월 25일 이후. 기본 자격증명(credentials) 정책이 same-origin 으로 변경되었습니다. 파이어폭스는 61.0b13 이후 변경되었습니다.
주의점을 살펴보았으니 각설하고, fetch API의 사용을 위해 간단한 방법을 알아보겠습니다.
// url은 필수, options는 선택사항
fetch(url, options)
너무 간단했나요? 아래는 fetch API의 디테일한 사용방법입니다.
fetch(url, {
method: 'GET' // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // no-referrer, *client
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
.then(response => response.json());
// 응답받은 JS오브젝트를 JSON객체로 변환합니다.
// JSON 구조의 데이터를 사용하기위해 변환작업을 하는 것입니다.
.then(response => response.html());
// 응답받은 JS오브젝트를 html객체로 변환합니다.
// html 구조의 데이터를 사용하기위해 변환작업을 하는 것입니다.
읽기 싫어지시죠? 글자가 많으면 읽기 싫어지는 법입니다. 하지만 메뉴얼을 잘 읽어야 제대로 사용할 수 있습니다. 메뉴얼을 잘 읽어보는 습관이 중요합니다. 그럼 테스트로 fetchAPI를 사용해보겠습니다. 일단 Chrome 브라우저를 열어서 F12(macOS 사용자의 경우 cmd + alt + i)를 눌러 개발자도구를 엽니다. console 을 찾아 아래의 코드를 입력합니다. 아래는 fetch API로 요청하고, 응답을 확인하는 코드입니다.
const response = fetch("https://jsonplaceholder.typicode.com/todos/1");
console.log(response)
콘솔에 입력후 엔터를 치자마자 응답이 올겁니다. 응답된 객체는 역시 Promise객체입니다.
► Promise {<pending>}
이 Promise객체의 상태를 가볍게 뜯어보면 아래의 형태로 되어있습니다.
▼Promise {<pending>}
►__proto__: Promise
[[PromiseStatus]]: "resolved"
►[[PromiseValue]]: Response
잠시 설명을 드리자면 __proto__에는 Promise의 내부함수들이 들어가있습니다. [[PromiseStatus]]에는 기다린 데이터가 왔다는 의미의 'resolved' 그리고 [[PromiseValue]]에는 Response에 대한 Header정보들이 들어가있습니다. 더 자세히 설명하면 Promise에 대한 소개로 빠질 것 같으니 이만 줄이겠습니다.
Promise가 생소하신 분들은 Promise가 왔는데 뭐 어쩌라고? 빨리 원하는 데이터를 보여줘!!! 라고 생각하실 수 있는데요. 그런 분들을 위해 지금 바로 console에 아래의 코드를 입력하여, 방금보낸 요청에 대한 응답을 확인해보겠습니다.
response
.then(result => result.json())
.then(json => {
console.log(json);
});
풀어서 설명드리자면, 첫번째 then에서는 result를 json객체로 변환하여 리턴합니다. 두번째 then에서는 첫번째 then에서 리턴한 데이터를 json이라는 인자에 담아와서 console.log로 데이터를 보여줍니다. 참고로 then이 반환값을 있다면 직후 then이 직전 then반환값을 인자에 담아서 쓸 수 있는데요. 이러한 기술명칭을 Promise Chaining이라고합니다.
또한 fetch API로 요청한 https://jsonplaceholder.typicode.com/todos/1 API는 요청시 반드시 JSON으로 반환(응답)되어야한다는 약속이 되어 있기때문에 json()을 쓴 것입니다. 만약 반환값이 HTML구조의 객체였다면 html()을 사용하여 변환(파싱)해야합니다. (예: result.html())
응답온 데이터 확인하기
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
fetch API에 대한 사용법을 간단하게 알아봤습니다. 추가로 http, https 등은 외부로부터 데이터를 내부로 가져오는 것이기때문에 보안이 중요한 사이트에서는 옵션설정을 꼼꼼하게 잘 해주어야합니다.
참고인용
fetch API의 대해서
https://developer.mozilla.org/ko/docs/Web/API/Fetch_API
fetch API의 사용법https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Fetch%EC%9D%98_%EC%82%AC%EC%9A%A9%EB%B2%95