처음에는 Ajax
에 대해서만 깊게 정리하려고 했지만, 우리가 Ajax
이외에도 클라이언트와 서버 사이에 데이터를 비동기 통신을 할때 Axios
, fetch
를 사용하고 있다. 그래서 이 두가지 방법과 같이 Ajax
와 연관지어서 한번 각각의 특징과 장, 단점을 한번 같이 정리해보려고 한다.
var xhr = new XMLHttpRequest(); // 객체 생성
xhr.onreadystatechange = function() { // 요청에 대한 콜백
if (xhr.readyState === xhr.DONE) { // 요청이 완료되면
if (xhr.status === 200 || xhr.status === 201) {
console.log(xhr.responseText);
} else {
console.error(xhr.responseText);
}
}
};
xhr.open('GET', 'https://localhost:3000'); // 메소드와 주소 설정
xhr.send(); // 요청 전송
// xhr.abort(); // 전송된 요청 취소
위는 전통전인 Ajax 사용코드 이다.
- XMLHttpRequest Object를 만든다.
- request를 보낼 준비를 브라우저한테 시키는 과정이다.
- 필요한 method를 갖춘 Object가 필요하다.
- callback 함수를 만든다.
- 서버에서 response가 왔을 때 실행하는 함수
- HTML 페이지를 업데이트 한다.
- Open a request
- 서버에서 response가 왔을 때 실행 시키는 함수
- HTML 페이지를 업데이트 한다
- send the request
오래전에는 서버에서 데이터를 받아오는데 XML
이 사용되었으나, 현재는 기본적으로 json
형식으로 받고 있다.
XMLHTTPRequest
를 통해 통신을 하는 경우 사용자에게 아무런 정보가 주어지지 않아서 아직 요청이 완료되지 않았는데 페이지를 떠나거나 오작동 할 우려가 발생한다.보통 Ajax
에 대해 말을 하다보면 JQuery
와 Ajax
를 같이 말하는 경우가 많다. 하지만 이와 같은 경우는 Ajax
라는 친구를 JQuery
를 통해 보다 더 쉽고, 깔끔하게 사용할 수 있기 때문이지 두개가 절대 같은 의미를 받아들이면 안된다. Ajax
는 크기가 커지면 코드가 매우 지저분했기에 이에 대한 보완이 필요했고, 그러던 도중에 JQuery
에서 Ajax
를 편리하게 사용할 수 있도록 정리하면서 급부상하게 된 것이다. ( 물론 JQuery
코드 자체가 워낙 간단한 이유가 있다.)
var serverAddress = 'https://jsonplaceholder.typicode.com/posts';
// jQuery의 .get 메소드 사용
$.ajax({
url: ,
type: 'GET',
success: function onData (data) {
console.log(data);
},
error: function onError (error) {
console.error(error);
}
});
JQuery
를 통해 Ajax
를 사용했을 때보다 훨씬 간단하고, 직관적이다.Ajax
로만 구현 시에는 브라우저 간 호환성에 대해 염두해두고 각 다른 코드를 작성해야하는 경우가 있는데 JQuery
를 사용할 경우 호환성에서도 보장이 된다. 지금은 왜 JQuery
를 지양하는지에 대해 간단하게 넘어가보면 크게 3가지 이유로 볼 수 있다.
- 사용할 이유가 딱히 없다. 과거와 달리 크로스 브라우징 이슈도 적어졌고,
virtual DOM
의 인기로DOM
을 직접 조작할 필요가 없다.JQeury
는 기존 코드를 래핑해서 새롭게 만든 패키지이다. 문제는 이러한 래핑이 지나치게 많고, 애초에 최적화를 고려하지 않고 만들어졌다.- 좋은 대안이 많이 생겼다. 우리가 보통 사용하는
React
만해도 재사용성을 높인 컴포넌트 기반으로JQuery
보다 훨씬 가독성이 높은 코드를 작성 할 수 있다.
이렇게 3가지 이유를 볼 수 있는데 워낙 다양한 라이브러리와 프레임워크가 나오면서 당장 앞에 문제에 대한 답을 얻기보다는 어떻게 효과적으로 답을 도출할것인지에 대한 과정의 중요성이 커졌기 때문이라고 할 수 있다.
//fetch
const url ='http://localhost3000/test`
const option ={
method:'POST',
header:{
'Accept':'application/json',
'Content-Type':'application/json'
},
body:JSON.stringify({
name:'changhyeon',
age:29
})
fetch(url,options)
.then(response => console.log(response))
.catch(error => console.log(error))
- 내장 라이브러리이기 때문에 import 하지 않아도 사용이 가능하다.
- 라이브러리 업데이트에 따른 에러방지가 가능하다.
(React-Native의 경우 잦은 업데이트로 인해 브라우저가 쫒아오지 못하는 경우가 많은데, fetch의 경우 이를 방지 할 수 있다.)
- 네트워크 에러가 발생했을 때 기다려야 한다. (response timeout API 제공 X)
- 지원하지 않는 브라우저가 있다.
- return 값이 Promise라서 관리가 쉽다.
//axios
const option ={
url ='http://localhost3000/test`
method:'POST',
header:{
'Accept':'application/json',
'Content-Type':'application/json'
},
data:{
name:'baechang',
age:30
}
axios(options)
.then(response => console.log(response))
.catch(error => console.log(error))
- reponse timeout(fetch에 없는 기능) 처리방법이 존재한다.
- Promise 기반으로 만들어졌기 때문에 데이터 다루기가 편하다.
- 크로스 브라우징 최적화로 브라우저 호환성(구형 브라우저 지원)이 뛰어나다.
- request aborting(요청 취소)가 가능하다.
- JSON 데이터 자동변환이 가능하다.
- 사용을 위해 모듈 설치가 필요하다 (npm i axios, yarn add axios)
Axios | Fetch |
---|---|
써드파티 패키지로 설치가 쉽다. | Built-in APIs로 별도의 설치가 필요없이, 모던 브라우저에서 사용이 가능하다. |
wide browser 지원 | 오직 크롬 42+, firefox 39+, edge 14+, safari 10.1+ 지원. polyfill 이용해서 하위 호환성 지원 가능 |
XSRF Protection 보안 기능 제공 | 없음 |
자동 JSON 데이터 변환 | JSON 데이터 핸들링 위해 추가 절차 필요 |
Request취소와 Request Timeout 설정 가능 | 없음 ( AbortController 이용하여 구현 가능 ) |
HTTP Requests의 Intercept 가능 | Intercept Requests 제공 X (Global Fetch Method 를 Overwrite하여 인터셉터 정의는 가능) |
Download Progress 지원 | Upload Progress 지원 X (Response Object의 Body Property 통해 제공되는 ReadableStream 인스턴스 이요 가능) |
표를 통해 비교하면 얼핏 비슷해보이는 두가지 방법이 다르다는것을 알 수 있다.
- fetch는 body 프로퍼티를 사용하고, Axios는 data 프로퍼티를 사용한다.
- fetch의 url fetch함수의 인자로 들어가고, Axios는 url이 option객체로 들어간다.
- fetch에서 body 부분은 stringify()가 된다.
이처럼 Axios는 상대적으로 HTTP 통신의 요구사항을 컴팩트하게 보여주는 패키지로써 사용하기 쉽게 설계되어있는 것을 알 수 있다.
그러면 어떨때 두가지 방법 중 골라서 쓰면 되는 걸까?
먼저 프로젝트의 성격을 파악해서 각 장,단점에 맞게 사용하면 베스트이긴한데 간단한 통신의 경우에는 fetch
를 사용하고 구조가 복잡하고 규모가 커지는 경우에는 조금 더 직관적인 Axios
를 사용하면 될거 같다.
위에서도 설명했지만 업데이트가 잦은 React-Native
같은 경우에는 Built-in APIs인 fetch
를 사용함으로써 더 안정적으로 운영이 가능할거 같다.
정확하지 않은 정보가 있을 수 있습니다. 댓글을 통해 피드백 주시면 적극적으로 반영하겠습니다🥲