비동기 HTTP 통신
- 서버와 데이터를 주고받기 위한 비동기 HTTP 통신.
- 비동기 통신은 페이지 새로고침 없이 서버와 통신하여 동적인 콘텐츠를 로드하고 업데이트하는 데 사용.
- 주로 사용하는 비동기 HTTP 통신은 Ajax, Axios, Fetch.
비동기 통신의 필요성
- 초기 정적(static) 웹에서 동적(dynamic)인 웹으로 페러다임 전환.
- 동기적 통신은 완료될 때 화면의 깜빡임이 발생,
- 예를 들면, 페이스북의 좋아요 증가 => 페이지 새로 고침(갱신)
- 또한 용량이 클 수록 로딩 시간이 길어짐.
- 비동기 통신은 깜빡임 없이(새로 고침이 필요없음) 데이터를 표현 할 수 있고,
- 초기 화면 구성 등에서도 이점(빠름)을 가짐.
- 또한 Lazy Loading 등 필요한 부분만 업데이트하고 불필요한 데이터 전송을 최소화.
Ajax(Asynchronous JavaScript and XML)
GET 예제
function getData(url, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = () => {
if (xhr.status === 200) {
const response = JSON.parse(xhr.responseText);
callback(null, response);
} else {
const error = new Error('Error: ' + xhr.status);
callback(error);
}
};
xhr.onerror = () => {
const error = new Error('Request failed');
callback(error);
};
xhr.send();
}
getData('API URL', (error, data) => {
if (error) {
console.error(error);
} else {
console.log(data);
}
});
POST 예제
function postData(url, data, callback) {
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
const response = JSON.parse(xhr.responseText);
callback(null, response);
} else {
const error = new Error('Error: ' + xhr.status);
callback(error);
}
};
xhr.onerror = () => {
const error = new Error('Request failed');
callback(error);
};
xhr.send(JSON.stringify(data));
}
const newPost = {
title: 'New Post',
content: 'This is a new post content.',
};
postData('API URL', newPost, (error, data) => {
if (error) {
console.error(error);
} else {
console.log(data);
}
});
Fetch API
Promise
기반.
- ES6부터 추가된 Web APIs.
- 에러 발생 시
response timeout
이 없음.
body
속성을 사용하고, 문자열화 되어있음.
JSON
<-> object/array
변환 필요.
reponse
객체가 "OK"
속성을 포함하면 성공.
GET 예제
fetch('API URL')
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error('Error: ' + response.status);
}
})
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
});
POST 예제
fetch('API URL', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'New Post',
content: 'This is a new post content.',
}),
})
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error('Error: ' + response.status);
}
})
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
});
Axios(Promise-based HTTP 클라이언트)
Promise
기반.
- 브라우저와 Node.js 환경에서 모두 사용할 수 있는 내장된 HTTP 클라이언트 활용.
data
속성을 사용하고, object
(객체)를 포함.
JSON
<-> object/array
자동으로 변환.
status: 200
또는 statusText: "OK"
라면 성공.
- XSRF(사이트 간 요청 위조) 보호.
- 요청(Request) 취소와 요청 TimeOut 설정 가능.
- 라이브러리 설치 필요.
npm install axios
<script src="./node_modules/axios/dist/axios.min.js"></script>
import axios from 'axios'
GET 예제
axios
.get('API URL')
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error(error);
});
POST 예제
axios
.post('API URL', {
title: 'New Post',
content: 'This is a new post content.',
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error(error);
});
async/await 사용
Axios
, Fetch
에서 사용 가능.
- 간결하고, 동기적인 코드 스타일로 작성 가능.
- 가독성 향상과 오류 처리의 직관성.
async function postData() {
try {
const response = await axios.post('API URL', {
title: 'New Post',
content: 'This is a new post content.',
});
console.log(response.data);
} catch (error) {
console.error(error);
}
}
postData();
요청 쉬소 토큰
- HTTP 요청 취소를 간편하게 처리.
catch
문 안에서 axios.isCancel()
을 통해 취소 인지 가능.
const source = axios.CancelToken.source();
axios
.post(
'API URL',
{
title: 'New Post',
content: 'This is a new post content.',
},
{ cancelToken: source.token }
)
.then((response) => {
console.log(response.data);
})
.catch((error) => {
if (axios.isCancel(error)) {
console.log('요청이 취소되었습니다:', error.message);
} else {
console.error(error);
}
});
source.cancel('사용자가 요청을 취소함');
TimeOut 설정
- Axios의 타임아웃은 연결 시간 초과, 응답 시간 초과 에서 적용됨.
- 타임아웃 시간을 초과하면 요청을 취소함.
error.code === 'ECONNABORTED'
로 설정.
axios
.post(
'API URL',
{
title: 'New Post',
content: 'This is a new post content.',
},
{ timeout: 5000 }
)
.then((response) => {
console.log(response.data);
})
.catch((error) => {
if (error.code === 'ECONNABORTED') {
console.log('요청이 타임아웃되었습니다:', error.message);
} else {
console.error(error);
}
});