AJAX 등장 이전에는 ‘좋아요 버튼’의 상태 변화를 나타내기 위하여 서버로 요청을 보내고 상태 변화할 요소 포함 해당 페이지의 모든 화면 구성 요소들을 다시 받았다.
매번 리소스가 새로 받아와야 하기때문에 네트워크 트래픽에 큰 낭비가 발생했다.

AJAX 등장 이후, 부분 요소의 상태 변화를 위하여 해당 페이지에 대한 모든 리소스를 요청하는 것이 아니라 변화가 필요한 부분에 대한 HTTP 요청을 전송하여 해당 부분만 변화할 수 있도록 한다. 이때 DOM을 사용하여 해당 부분만 동적으로 변화할 수 있게 한다.
즉, 변화가 필요한 부분만 부분적으로 리로드 할 수 있게 되었다.
AJAX이 출시 되었을 시 XML 타입을 통한 데이터 전송이 주를 이루었으나 현재는 JSON 타입이 가장 많이 사용되고 이 외의 타입의 데이터를 통한 전송도 가능하다.
비동기적이란 작업이 독립적으로 진행된다는 것이라 간단히 말할 수 있다. AJAX은 비동기적으로 진행되기 때문에 웹 페이지에서 진행되고 있는 다른 작업들을 방해하지 않고 부분 상태 변화를 할 수 있도록 한다.
WEB API의 일부인 XMLHTTPRequest와 Fetch API를 통해서 구현할 수 있다.
index.html <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../style.css">
<script defer src="./script.js"></script>
<title>API</title>
</head>
<body>
<header>
<h1>API</h1>
</header>
<main>
<section>
<iframe width="800" height="450" src="https://www.youtube.com/embed/5-aShyk1FHc?si=6G0VhSR-wK-V0jW_" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</section>
<section id="contents">
<nav>
<ul>
<li class="restapi">REST API</li>
<li class="graphql">GraphQL</li>
<li class="websocket">WebSocket</li>
<li class="sse">SSE</li>
</ul>
</nav>
<h2></h2>
<p></p>
</section>
</main>
</body>
</html>
script.js (XMLHTTPRequest version)
function getContents(code) {
const xhr = new XMLHttpRequest();
xhr.open('GET', './apis.json', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
const data = JSON.parse(xhr.responseText);
const api = data.find(api => api.code === code);
document.querySelectorAll('#contents nav ul li')
.forEach(li => { li.classList.remove('selected') });
document.querySelector(`#contents nav ul li.${code}`)
.classList.add('selected');
document.querySelector('#contents h2')
.textContent = api.name;
document.querySelector('#contents p')
.textContent = api.content;
} catch (e) {
console.error('Error parsing JSON:', e);
}
} else {
console.error('Network response was not ok');
}
}
};
xhr.onerror = function() {
console.error('Request error');
};
xhr.send();
}
document.querySelectorAll('#contents ul li')
.forEach(li => {
li.addEventListener('click', function(e) {
const code = Array.from(e.target.classList)
.find(c => { return c != 'selected' })
getContents(code);
});
});
getContents('restapi');
서버로 부터 받아온 데이터를 JSON타입으로 파싱하여 데이터 추출하고,
이후 DOM을 사용하여 요소들을 선택 후 데이터를 바인딩한다.
script.js (Fetch API version)
function getContents (code) {
fetch('./apis.json')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
const api = data.find(api => api.code === code);
document.querySelectorAll('#contents nav ul li')
.forEach(li => {li.classList.remove('selected')})
document.querySelector(`#contents nav ul li.${code}`)
.classList.add('selected');
document.querySelector('#contents h2')
.textContent = api.name;
document.querySelector('#contents p')
.textContent = api.content;
})
.catch(error => {
console.error('Error ocurred:', error);
});
}
document.querySelectorAll('#contents ul li')
.forEach(li => {
li.addEventListener('click', function(e) {
const code = Array.from(e.target.classList)
.find(c => { return c != 'selected' })
getContents(code);
});
});
getContents('restapi');
Ferch API는 자바스크립의 promise를 사용하여 작성한다. 따라서 method chaining을 통한 간결한 코드 작성이 가능하다.
오래된 브라우저의 경우 Fetch API가 지원되지 않을 수도 있지만 점점 더 많이 웹 서비스에 도입되고 있다.
더 강력한 기능을 사용하길 원한다면 axios와 같은 외부 라이브러리 사용도 고려해볼 수 있다.
‘ 얄팍한 코딩사전 -AJAX - 우리가 무한스크롤을 사용할 수 있는 이유’를정리하였습니다.