fetch()
를 사용하면 XMLHttpRequest (XHR)와 유사한 네트워크 요청을 할 수 있습니다. 주요 차이점은 Fetch API가 Promises를 사용한다는 점입니다. Promises에는 XMLHttpRequest API의 복잡한 콜백을 피하는 데 도움이 되는 더 간단한 API가 있습니다.
이전에 Promises를 사용한 적이 없다면 JavaScript Promises 소개를 확인하세요.
기본 가져오기 요청
다음은 XMLHttpRequest
로 구현된 다음 fetch
로 구현된 예입니다. URL을 요청하고 응답을 가져와 JSON으로 파싱하려고 합니다.
XMLHttpRequest
XMLHttpRequest
에는 성공 및 오류 사례를 처리하는 두 개의 리스너와 open()
및 send()
호출이 필요합니다.
MDN 문서의 예
function reqListener () {
const data = JSON.parse(this.responseText);
console.log(data);
}
function reqError (err) {
console.log('Fetch Error :-S', err);
}
const oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();
가져오기
가져오기 요청은 다음과 같습니다.
fetch('./api/some.json')
.then(response => {
if (response.status !== 200) {
console.log(`Looks like there was a problem. Status Code: ${response.status}`);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
})
.catch(err => {
console.log('Fetch Error :-S', err);
});
fetch()
요청은 XHR 예와 동일한 작업을 실행하는 데 한 번의 호출만 필요합니다. 응답을 처리하려면 먼저 응답 상태가 200인지 확인한 다음 응답을 JSON으로 파싱합니다. fetch()
요청에 대한 응답은 스트림 객체입니다. 즉, json()
메서드를 호출한 후 프로미스가 반환됩니다.
스트림은 비동기식으로 발생합니다.
응답 메타데이터
이전 예에서는 Response 객체의 상태와 응답을 JSON으로 파싱하는 방법을 보여줍니다. 헤더와 같이 액세스하려는 다른 메타데이터를 처리하는 방법은 다음과 같습니다.
fetch('users.json').then(response => {
console.log(response.headers.get('Content-Type'));
console.log(response.headers.get('Date'));
console.log(response.status);
console.log(response.statusText);
console.log(response.type);
console.log(response.url);
});
응답 유형
가져오기 요청을 실행하면 응답에 response.type
('basic
', 'cors
' 또는 'opaque
')가 제공됩니다. 이러한 types
는 리소스의 출처를 나타내며 이를 사용하여 응답 객체를 처리하는 방법을 결정할 수 있습니다.
브라우저가 동일한 출처의 리소스를 요청하면 응답에는 응답에서 볼 수 있는 항목에 대한 제한이 있는 basic
유형이 있습니다.
다른 출처의 리소스에 대한 요청이 이루어지고 해당 출처에서 CORs 헤더를 반환하면 유형은 cors
입니다. cors
응답은 basic
응답과 유사하지만 볼 수 있는 헤더를 Cache-Control
, Content-Language
, Content-Type
, Expires
, Last-Modified
, Pragma
로 제한합니다.
opaque
응답은 CORS 헤더를 반환하지 않는 다른 출처에서 가져옵니다. 불투명한 응답을 사용하면 반환된 데이터를 읽거나 요청 상태를 볼 수 없으므로 요청이 성공했는지 확인할 수 없습니다.
특정 요청 유형만 확인되도록 가져오기 요청의 모드를 정의할 수 있습니다. 설정할 수 있는 모드는 다음과 같습니다.
same-origin
는 동일한 출처의 애셋 요청에 대해서만 성공하고 다른 모든 요청은 거부합니다.cors
는 동일한 출처 및 적절한 CORs 헤더를 반환하는 다른 출처의 애셋에 대한 요청을 허용합니다.cors-with-forced-preflight
는 요청하기 전에 사전 비행 확인을 실행합니다.no-cors
는 CORS 헤더가 없고opaque
응답을 반환하는 다른 출처에 요청을 보내기 위한 것이지만, 앞서 언급한 대로 현재는 window 전역 범위에서 불가능합니다.
모드를 정의하려면 fetch
요청에 두 번째 매개변수로 옵션 객체를 추가하고 해당 객체에서 모드를 정의합니다.
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
.then(response => response.text())
.then(text => {
console.log('Request successful', text);
})
.catch(error => {
log('Request failed', error)
});
Promise 체이닝
약속의 큰 장점 중 하나는 약속을 서로 연결할 수 있다는 점입니다. fetch()
의 경우 가져오기 요청 간에 로직을 공유할 수 있습니다.
JSON API를 사용하는 경우 상태를 확인하고 각 응답의 JSON을 파싱해야 합니다. 약속을 반환하는 별도의 함수에서 상태와 JSON 파싱을 정의하고 가져오기 요청을 사용하여 최종 데이터와 오류 사례만 처리하여 코드를 간소화할 수 있습니다.
function status (response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
function json (response) {
return response.json()
}
fetch('users.json')
.then(status)
.then(json)
.then(data => {
console.log('Request succeeded with JSON response', data);
}).catch(error => {
console.log('Request failed', error);
});
이 예에서는 response.status
를 확인하고 해결된 Promise를 Promise.resolve()
로 반환하거나 거부된 Promise를 Promise.reject()
로 반환하는 status
함수를 정의합니다.
fetch()
체인에서 호출되는 첫 번째 메서드입니다.
프로미스가 확인되면 스크립트는 json()
메서드를 호출합니다. 이 메서드는 response.json()
호출에서 두 번째 프로미스를 반환하고 파싱된 JSON이 포함된 객체를 만듭니다. 파싱에 실패하면 Promise가 거부되고 catch 문이 실행됩니다.
이 구조를 사용하면 모든 가져오기 요청에서 로직을 공유할 수 있으므로 코드를 더 쉽게 유지 관리, 읽고 테스트할 수 있습니다.
POST 요청
웹 앱에서 POST 메서드로 API를 호출하고 요청 본문에 일부 매개변수를 포함해야 하는 경우가 있습니다. 이렇게 하려면 fetch()
옵션에서 method
및 body
매개변수를 설정합니다.
fetch(url, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
})
.then(json)
.then(data => {
console.log('Request succeeded with JSON response', data);
})
.catch(error => {
console.log('Request failed', error);
});
가져오기 요청으로 사용자 인증 정보 전송
쿠키와 같은 사용자 인증 정보로 가져오기 요청을 하려면 요청의 credentials
값을 "include"
로 설정합니다.
fetch(url, {
credentials: 'include'
})