모던 브라우저에서 비동기 네트웍 요청하기
개요
옛날에는 XHR a.k.a. AJAX를 썼다. 쌩으로 쓰긴 번거로우니 jQuery 같은걸 이용했다. 비동기 호출을 편하게 쓸 수 있었고, 새로운 브라우저와 구닥다리 브라우저를 모두 지원할 수 있었다.
Fetch API는 비동기 네트웍 요청을 표준하며 만들어졌고, Promise 기반으로 구성된다.
IE만 빼면 그럭저럭 지원이 잘 된다. (참고 - https://caniuse.com/#feat=fetch ) 공식적으로 지원되지 않는 브라우저에서는 polyfill 을 쓰면 된다.
기본 사용법
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => {
console.dir(response.headers.get('Content-Type'));
console.log(response.status);
console.log(response.statusText);
console.log(response.url);
return response.json();
})
.then(body => console.log(body))
.catch(err => console.error(err))
fetch()는 글로벌window스코프에 있는 함수라서 바로 쓸 수 있다. 가장 간단한 사용법은 인자로 들어온 리소스 경로를 하나 넘기는 것이다. 이렇게 하면 해당 리소스 경로로GET요청을 보낸다.fetch()는 비동기 호출 결과를Promise객체로 리턴하므로then()메소드를 이용해서 결과를 처리한다.then()메소드에서는Response객체를 받는다.catch()메소드는Promise에서 요청 수행 도중에 에러가 발생할 경우 처리가 넘어가서 에러 핸들링 할 수 있는 부분이다.Response객체에는 네트웍 요청에 대한 응답 결과가 담겨 있다.response.headers,response.status,response.statusText,response.url등의 메타 정보를 사용할 수 있다.- 응답의 body는 html 인 경우,
response.text()으로, json인 경우response.json()으로 얻을 수 있다.
Request 옵션
fetch() 메소드에 리소스 경로 하나만 넣으면 디폴트로 GET 요청을 보내지만, request 옵션 객체를 넘기면 다른 요청도 가능하다. 혹은, 같은 설정으로 Request 객체를 만들어서 그 객체 하나만 fetch() 에 넘겨도 같은 결과를 얻을 수 있다.
fetch('https://jsonplaceholder.typicode.com/posts', {
//디폴트 옵션에 * 표시 있음.
method: 'POST', // *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; charset=UTF-8"
// "Content-Type": "application/x-www-form-urlencoded",
},
redirect: "follow", // manual, *follow, error
referrer: "no-referrer", // no-referrer, *client
body: JSON.stringify({ // body data type must match "Content-Type" header
title: 'foo',
body: 'bar',
userId: 1
}),
})
.then(response => response.json())
.then(json => console.log(json))
참고
- https://fetch.spec.whatwg.org/
- https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
- https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
- https://medium.freecodecamp.org/understanding-the-fetch-api-a7d4c08c2a7
- https://github.com/github/fetch
await fetch
fetch() 의 리턴값은 promise 라서 콜백 함수 안에서 쓰거나 해야하는데, 리턴값을 동기 코드의 리턴 값을 쓰는것처럼 바로 쓰려면 await 연산자를 이용할 수 있다.
await은 promise를 기다리게 해준다. 그리고 async 함수 안에서만 사용할 수 있다.
그냥 짧은 요청을 테스트해보는 정도에서는 아래와 같은 코드 조각을 활용할 수 있다.
(async () => {
let response = await fetch(api);
let body = await response.json();
console.log(body.data);
})();
위 섹션에서 사용한 예제코드는 아래와 같이 옮길 수 있다.
(async () => {
let response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
let body = await response.json();
console.log(body)
})();
참고
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function