안녕하세요. 이번 시간에는 Fetch API에 대해 알아보겠습니다.
지난 시간에 배운 XHR 객체에 대해서는 어떻게 생각하시나요? 쓸 만한 것 같나요? 상당히 복잡하고 가독성이 떨어집니다. 그래서 나온 API가 Fetch API입니다. 단, 최신 API이기 때문에 아쉽게도 IE에서는 사용할 수 없습니다.
Fetch API를 알기 전에 Promise에 대한 이해가 먼저 필요합니다. 이 강좌에서 개념을 익히고 오셔야 합니다. 왜냐하면 fetch 요청 후에 return 값이 Promise 객체이기 때문이죠. 참고로 Promise 객체는 ES2015 스펙이기 때문에 ES2015 문법을 사용하겠습니다. fetch 함수도 window 아래에 위치합니다.
fetch('주소', 설정객체).then(콜백).catch(콜백);
기본적인 구조입니다. 주소에 요청을 보낼 주소를 입력해주고, 설정 객체에 GET, POST 등의 메소드, 보낼 데이터 등을 넣을 수 있습니다. then에서 응답 response 객체를 받고요. catch에서는 요청에 대한 에러를 받습니다.
fetch('https://www.zerocho.com/api/get').then((res) => {
if (res.status === 200 || res.status === 201) { // 성공을 알리는 HTTP 상태 코드면
res.text().then(text => console.log(text)); // 텍스트 출력
} else { // 실패를 알리는 HTTP 상태 코드면
console.error(res.statusText);
}
}).catch(err => console.error(err));
넵. 응답으로 받는 res는 Response 객체입니다. Response 객체는 응답에 대한 정보를 담고 있습니다. 객체 안의 status와 statusText 등은 성공 여부를 판가름할 때 쓰시면 되고요. headers는 응답에 대한 헤더 정보를 담고 있는 Headers 객체입니다. body는 응답 내용인데 Stream으로 되어 있어 쉽게 값을 볼 수 없습니다. 따라서 Response 객체에서 값을 볼 수 있게 해주는 메소드 5가지가 있습니다.
text, arrayBuffer, blob, json, formData입니다. 모두 Promise를 return합니다. 그래서 위에서 res.text().then(text => console.log(text))
으로 또 한 번 결과를 Promise로 받았습니다. 만약 json 데이터가 응답으로 오면 res.json().then(json => console.log(json));
이렇게 받으면 되겠죠? blob이나 arrayBuffer는 이미지나 파일같은 데이터일 때 사용하면 됩니다.
잠깐 Headers 객체에 대해 알아봅시다. Headers는 formData와 스펙이 비슷합니다. append, delete, entries, get, has, keys, set, values 메소드를 지원합니다.
res.headers.entries().next().value; // ['content-type', 'text/html; charset=utf-8']
이렇게 응답 헤더에 대한 정보를 확인할 수 있습니다. fetch 함수의 인자로 주소와 설정객체 대신에 Request 객체를 보낼 수도 있습니다. Request 객체는 fetch안의 주소, 설정객체를 인자로 받습니다. 네, 여기서 알 수 있는 점은 Request 객체는 특수한 경우를 제외하고는 쓸 필요가 없다는 겁니다. Request 객체도 인자로 주소와 설정객체를 받고, fetch함수도 인자로 주소와 설정객체를 받기 때문에 그냥 fetch함수만 사용하면 됩니다.
const req = new Request('https://www.zerocho.com/api/get');
fetch(req).then((res) => { // Request 객체에 주소를 넣느니 그냥 fetch에 넣으면 됨
if (res.status === 200 || res.status === 201) { // 성공을 알리는 HTTP 상태 코드면
res.text().then(text => console.log(text)); // 텍스트 출력
} else { // 실패를 알리는 HTTP 상태 코드면
console.error(res.statusText);
}
});
json을 전송하는 POST 요청을 보내봅시다.
const body = { name: 'zerocho' };
fetch('https://www.zerocho.com/api/post/json', {
method: 'POST',
body,
headers: new Headers(), // 이 부분은 따로 설정하고싶은 header가 있다면 넣으세요
}).then((res) => {
if (res.status === 200 || res.status === 201) {
res.json().then(json => console.log(json));
} else {
console.error(res.statusText);
}
}).catch(err => console.error(err));
이제 formData를 사용해서 POST 요청을 보내봅시다.
const formData = new FormData();
formData.append('name', 'zero')
fetch('https://www.zerocho.com/api/post/formdata', {
method: 'POST', // POST 메소드 지정
body: formData, // formData를 데이터로 설정
}).then((res) => {
if (res.status === 200 || res.status === 201) {
res.json().then(json => console.log(json));
} else {
console.error(res.statusText);
}
}).catch(err => console.error(err));
다시 말씀드리지만 Node.js로 폼데이터를 처리하는 방법은 이 강좌 에 나와있습니다.
이렇게 보니까 XHR 객체보다 가독성이 낫거나 그러진 않은 것 같네요;; IE도 지원하지 못 하고요. 하지만 Headers, Request, Response같은 객체를 직접 다룰 수 있습니다. 또 Promise를 선호하시는 분도 좋아할 것 같습니다. jQuery의 deferred, axios의 Promise와 문법이 유사합니다. 선택은 여러분의 몫입니다!