요즘 서버로부터 데이터를 받아오거나 보내서 작업하는 일이 점점 더 많아지면서 HTTP 요청 코드를 자주 짜게 된다.
앞으로 HTTP 요청은 눈 감고도 할 수 있을 만큼이 되어야 할 테니 복습 차원에서 HTTP 요청을 위한 fetch와 Axios에 대해 간단히 정리해 보도록 하자.
Fetch와 Axios
Fetch와 Axios는 모두 프로미스 기반의 HTTP 클라이언트다. 즉, 이 방식들을 이용해서 네트워크 요청을 하면 이행 또는 거부 상태를 가지는 프로미스가 반환된다.
데이터 요청하기
Fetch는 두 개의 인자를 받는다. 첫번째 인자는 리소스의 url이고, 두번째 인자는 요청의 설정 옵션이다. 두번째 인자는 생략 가능하다.
fetch(url, {
method: "GET", //(POST, PUT, DELETE, etc.)
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
Axios도 위와 동일하게 쓸수도 있고, HTTP 메서드를 바로 붙일 수도 있다.
axios(url, {
// 설정 옵션
});
axios.get(url, {
// 설정 옵션
});
데이터 사용하기
fetch()는 .then() 메서드에서 처리된 프로미스를 반환한다. 그러나 이 단계에서는 아직 JSON 데이터의 포맷이 아니기 때문에 .json() 메서드를 호출해서 데이터를 변환해 준다. 그 다음 JSON 형식의 데이터로 이행(resolve)된 또 다른 프로미스가 반횐되면 그때 데이터를 사용할 수 있다. 따라서 일반적인 fetch 요청은 두 개의 .then() 호출을 갖는다.
fetch(url)
.then((response) => response.json())
.then(console.log);
반면 Axios를 사용하면 응답 데이터를 기본적으로 JSON 타입으로 사용할 수 있다. 응답 객체의 data 프로퍼티로 받아온 데이터를 사용할 수 있다.
axios.get(url).then((response) => console.log(response.data));
데이터 전송하기
서버에 데이터를 전송하기 위해서는 데이터를 JSON 문자열로 직렬화해야 한다.
Fetch API를 사용해 데이터를 전송할 때는 JSON.stringify()를 사용하여 객체를 문자열으로 변환한 뒤 body에 할당해야 한다. 또 Content-Type을 application/json으로 설정해야 한다.
const todo = {
title: "A new todo",
completed: false,
};
fetch(url, {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(todo),
})
.then((response) => response.json())
.then((data) => console.log(data));
Axios를 사용해 POST 메서드로 데이터를 전송하면 자동으로 데이터를 문자열로 변환해준다. 요청 본문(request body)으로 보내고자 하는 data는 data 프로퍼티에 할당한다. 또, 기본적으로 Axios는 Content-Type을 application/json으로 설정해 준다.
const todo = {
title: "A new todo",
completed: false,
};
axios
.post(url, {
headers: {
"Content-Type": "application/json",
},
data: todo,
})
.then(console.log);
에러 처리
Fetch와 Axios는 모두 이행(resolve) 되거나 거부(reject)된 프로미스를 반환한다. 프로미스가 거부(reject)되면 .catch()를 사용하여 에러를 처리할 수 있다.
Fetch를 사용할 때는 404 에러나 다른 HTTP 에러 응답을 받았을 때 프로미스를 거부(reject)하지 않고, 오직 네트워크 장애가 발생한 경우에만 프로미스를 거부한다. 따라서 .then절을 사용해 수동으로 HTTP 에러를 처리해야 한다.
fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error(
`This is an HTTP error: The status is ${response.status}`
);
}
return response.json();
})
.then(console.log)
.catch((err) => {
console.log(err.message);
});
이에 비해 Axois는 상태 코드가 2xx의 범위를 넘어가면 프로미스를 거부한다. 에러 객체에 응답(response) 또는 요청(request) 프로퍼티가 포함되어 있는지 확인해 에러에 대한 자세한 정보를 확인할 수 있다.
axios
.get(url)
.then((response) => console.log(response.data))
.catch((err) => {
// 에러 처리
if (err.response) {
// 요청이 이루어졌고 서버가 응답했을 경우
const { status, config } = err.response;
if (status === 404) {
console.log(`${config.url} not found`);
}
if (status === 500) {
console.log("Server error");
}
} else if (err.request) {
// 요청이 이루어졌으나 서버에서 응답이 없었을 경우
console.log("Error", err.message);
} else {
// 그 외 다른 에러
console.log("Error", err.message);
}
});
응답 시간 초과/ 요청 취소
Axios에서는 timeout 속성을 설정 객체에 추가하여 요청이 종료될 때까지의 시간을 밀리초로 지정할 수 있다.
axios
.get(url, {
timeout: 4000, // 기본 설정은 '0'
})
.then((response) => console.log(response.data))
.catch((err) => {
console.log(err.message);
});
Fetch를 통한 요청을 취소하기 위해서는 AbortController 인터페이스를 사용할 수 있다.
Fetch vs Axios
axios | fetch |
요청 객체에 url이 있다. | 요청 객체에 url이 없다. |
써드파티 라이브러리로 설치가 필요 | 현대 브라우저에 빌트인이라 설치 필요 없음 |
XSRF 보호를 해준다. | 별도 보호 없음 |
data 속성을 사용 | body 속성을 사용 |
data는 object를 포함한다 | body는 문자열화 되어있다 |
status가 200이고 statusText가 ‘OK’이면 성공이다 | 응답객체가 ok 속성을 포함하면 성공이다 |
자동으로 JSON데이터 형식으로 변환된다 | .json()메서드를 사용해야 한다. |
요청을 취소할 수 있고 타임아웃을 걸 수 있다. | 해당 기능 존재 하지않음 |
HTTP 요청을 가로챌수 있음 | 기본적으로 제공하지 않음 |
download진행에 대해 기본적인 지원을 함 | 지원하지 않음 |
좀더 많은 브라우저에 지원됨 | Chrome 42+, Firefox 39+, Edge 14+, and Safari 10.1+이상에 지원 |
참고 자료
'Javascript' 카테고리의 다른 글
[Javascript] 이벤트 (0) | 2023.08.21 |
---|---|
[Javascript] 웹팩, 바벨, 폴리필 (0) | 2023.08.18 |
[Javascript] 비동기 프로그래밍 (0) | 2023.03.20 |
[Javascript] 프로토타입 체인 (0) | 2023.03.16 |
[Javascript] 클래스와 객체지향 프로그래밍 (0) | 2023.03.15 |