Fetch API란
서버와 비동기적으로 통신하기 위해 XMLHttpRequest
를 사용해왔습니다.
하지만 사용성이 까다로워 jQuery.ajax
, axios
등과 같은 라이브러리를 사용하고 있습니다.
Fetch API
는 사용성 개선을 위한 라이브러리, 플러그인 설치의 번거로움을 해결하기 위해 브라우저에서 제공하는 API 입니다.
Fetch API
가 제공하는 전역 fetch()
메서드로 비동기적으로 서버와의 통신할 수 있습니다.
기본적인 Fetch 요청
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(data => console.log(data))
async, await
const getData = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
return await response.json()
}
const data = await getData()
console.log(data)
결과
{
userId: 1,
id: 1,
title: 'delectus aut autem',
completed: false
}
응답은 Response
객체로 전달되고, JSON 형태로 바로 받지 못합니다.
Response
는 HTTP 응답 전체를 나타내는 객체로, JSON 본문 콘텐츠를 추출하기 위해서는 json()
메서드를 호출해야 합니다.
json()
은 응답 본문 텍스트를 JSON으로 파싱한 결과를 담은 프로미스를 반환합니다.
에러 catch
fetch()
로부터 반환되는 Promise 객체는 404나 500와 같은 HTTP ERROR 상태를 reject 하지 않습니다.
대신 Response.ok
상태가 false인 resolve가 반환됩니다.
네트워크 연결이 실패하는 경우를 포함, 아예 요청을 완료하지 못한 경우 TypeError로 reject가 반환됩니다.
따라서 fetch()
가 성공했는지를 정확히 알아내려면 프로미스의 이행 여부를 확인한 후, Response.ok
속성의 값이 true인지도 확인해야 합니다.
예시)
fetch(url)
.then(response => {
console.log(response.ok)
if (response.ok) {
return response.json()
} else {
console.error('ERROR')
}
})
.then(data => console.log(data))
.catch(err => console.error(err))
async, await
const getData = async () => {
try {
const response = await fetch(url)
console.log(response.ok)
if (response.ok) {
return await response.json()
} else {
console.error('ERROR')
}
} catch (err) {
console.error(err)
}
}
const data = await getData()
console.log(data)
catch 결과
요청 URL https://jsonplaceholder.typicode.com/todos/1
요청 URL https://jsonplaceholder.typicode.com/todos/123456789
요청 URL https://jsonplaceholder.typicodes.com/todos/1
요청 옵션 제공
fetch()
는 선택적으로 두 번째 매개변수로 옵션 객체를 넣을 수 있습니다.
옵션 객체를 사용하면 여러가지 설정을 할 수 있습니다.
async function postData(url, data) {
// 옵션 기본 값은 *로 강조
const init = {
method: 'POST', // *GET, POST, PUT, DELETE 등
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
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data), // body의 데이터 유형은 반드시 "Content-Type" 헤더와 일치해야 함
}
const response = await fetch(url, init);
return response.json(); // JSON 응답을 네이티브 JavaScript 객체로 파싱
}
postData(url, { answer: 42 }).then((data) => {
console.log(data);
});
- method : 사용할 메소드를 선택
'GET', 'POST', 'PUT', 'DELETE'
- mode : ‘cors’ 등의 값을 설정
'cors', 'no-cors', 'same-origin'
- cache : 캐쉬 사용 여부
'no-cache', 'reload', 'force-cache', 'only-if-cached'
- credentials : 자격 증명을 위한 옵션 설정
'include', 'same-origin', 'omit'
- headers : 헤더에 전달할 값
{ 'content-Type': 'application/json' }
- referrerPolicy : 헤더에 포함되어야 하는 리퍼러 정보의 양
'no-referrer', 'no-referrer-when-downgrade', 'origin', ...more
Referrer-Policy 더보기 - redirect : 리다이렉트 설정
'manual', 'follow', 'error'
- body : 바디에 전달할 값
JSON.springfy(data)
]()
자격 증명 요청
credentials
옵션을 제공하지 않은 경우, fetch()
는 쿠키를 전송하지 않습니다.
쿠키를 전송하기 위해선 자격 증명을 전송 해야합니다.
아래 자격 증명 요청 옵션을 참고하여 브라우저 요청시 fetch()
의 옵션 객체에 설정을 추가해보세요.
credentials 옵션
include
: 동일 출처와 교차 출처 요청 모두에 사용same-origin
: 요청 URL이 스크립트와 동일 출처일 때 자격 증명 전송omit
: 자격 증명을 전송하지 않음
Redirect
Fetch API
를 통해 브라우저 요청 후 서버에서 리다이렉트를 하려고 할때 바로 리다이렉팅 페이지로 이동이 불가합니다.
리다이렉트를 하기 위해선 fetch()
의 두번째 파라미터 옵션 객체에서 redirect
의 설정이 필요합니다.
redirect 옵션
manual
: 리다이렉트를 허용하지 않는다.error
: 리다이렉트 응답을 에러로 처리한다.follow
: 리다이렉트 응답을 허용한다.
요청 후 Response
객체의 redirected
의 boolean 값을 통해 redirect 여부를 검사한다.
redirected 값
true
: 리다이렉트 요청false
: 리다이렉트 미요청
사용 예)
fetch(url)
.then((response) => {
if (response.redirected) response.redirect(response.url)
})
Fetch API에 대해 더 알아보고 싶다면
참고 자료
- https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch#%EB%8B%A4%EC%88%98%EC%9D%98%ED%8C%8C%EC%9D%BC%EC%97%85%EB%A1%9C%EB%93%9C
- https://developer.mozilla.org/en-US/docs/Web/API/Response/redirected
- https://www.daleseo.com/js-window-fetch/
- https://pstudio411.tistory.com/entry/fetch-API
- https://geometery-programing.tistory.com/41
- https://velog.io/@adam2/2019-12-25-1512-%EC%9E%91%EC%84%B1%EB%90%A8