AJAX는 "Asynchronous JavaScript and XML"의 약자이다.
웹 페이지가 서버로부터 데이터를 비동기적으로 가져오고, 이를 갱신하는 데 사용하는 기술이다.
AJAX의 핵심 아이디어는 웹 페이지 전체를 새로 고침하지 않고도 데이터를 비동기적으로 서버에 요청하고, 그 결과를 받아와서 페이지의 일부를 갱신할 수 있다는 점이다.
이는 웹 애플리케이션의 성능과 사용자 경험을 크게 향상시킨다.
AJAX를 이해하기 위해선 "서버"가 무엇인지 알아야 한다. 왜냐하면 서버랑 비동기적 통신하기 때문이다.
서버는 데이터를 관리하고, 요청에 따라 데이터를 제공하는 컴퓨터 프로그램 또는 시스템이다.
클라이언트는 서버에 요청을 보내고, 서버는 그 요청에 맞는 데이터를 찾아서 응답한다.
왜 AJAX가 중요한가?
예를 들어, 인터넷으로 쇼핑을 하고 있다고 상상해보자.
물건을 장바구니에 담을 때마다 페이지가 새로고침된다면 불편하겠지?
AJAX를 사용하면, 페이지를 다시 로드하지 않고도 장바구니 물건을 추가할 수 있다.
간단히 말해서,
1. 요청 보내기 : 웹 페이지에서 서버로 데이터를 요청함. 예를 들어, "이 제품의 가격이 얼마임?"라는 질문을 보냄.
2. 서버 응답 : 서버는 질문을 받고, 필요한 데이터를 찾아서 응답함. 예를 들어, "이 제품의 가격은 10,000원임"라고 답함.
3. 데이터 처리 : 웹 페이지는 서버의 응답을 받아서, 필요한 부분만 업데이트한다. 페이지 전체를 새로고침하지 않고도 필요한 정보만 바꿀 수 있다.
예시 코드
<!DOCTYPE html>
<html>
<head>
<title>AJAX 예제</title>
</head>
<body>
<h1>AJAX로 데이터 가져오기</h1>
<button id="loadData">데이터 가져오기</button>
<div id="result"></div>
<script>
document.getElementById('loadData').addEventListener('click', function() {
// 1. XMLHttpRequest 객체 생성
let xhr = new XMLHttpRequest();
// 2. 요청 준비
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1', true);
// 3. 요청 보내기
xhr.send();
// 4. 응답 처리
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
// 서버 응답 받기
let data = JSON.parse(xhr.responseText);
// 페이지에 결과 표시
document.getElementById('result').innerText = `제목: ${data.title}`;
}
};
});
</script>
</body>
</html>
Ajax와 fetch, Axios의 관계
Ajax는 특정한 라이브러리나 API가 아니라, 웹에서 데이터를 비동기적으로 가져오는 방법을 설명하는 개념이다. Ajax를 구현하는 다양한 방법 중에서 가장 기본적인 방법은 JS의 `XMLHttpRequest`객체를 사용하는 것이다.
그러나 `XMLHttpRequest`는 사용이 복잡하고 번거롭기 때문에, 이를 더 쉽게 사용할 수 있도록 돕는 라이브러리와 API가 발전했다. 이 중에서 fetch와 Axios는 Ajax 요청을 쉽게 만드는 방법 중 두 가지이다.
최신 자바스크립트 버전에서는 fetch와 axios를 쓴다.
fetch
- fetch는 브라우저 내장 API로, `XMLHttpRequest`의 현대적인 대안이다.
- Promise 기반으로 작동하여, 비동기 요청을 보다 직관적으로 처리할 수 있다.
- 문법이 간단하고, JSON 데이터의 처리가 용이하다.
Fetch API를 사용한 예시
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
<script>
document.getElementById('loadData').addEventListener('click', function() {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json()) // 응답을 JSON 형태로 변환
.then(data => {
document.getElementById('result').innerText = `제목: ${data.title}`;
})
.catch(error => console.error('Error:', error)); // 오류 처리
});
</script>
Axios
- Axios는 HTTP 요청을 보다 쉽게 처리할 수 있게 해주는 자바스크립트 라이브러리이다.
- Promise 기반이며, 클라이언트(브라우저)뿐만 아니라 Node.js 환경에서도 사용할 수 있다.
- 요청 및 응답의 인터넵터, 요청 취소, JSON 자동 변환 등 다양한 기능을 제공한다.
Axios를 사용한 예시
import axios from 'axios';
axios.get('https://api.example.com/data')
.then(response => console.log(response.data))
.catch(error => console.error('Error:', error));
<script>
document.getElementById('loadData').addEventListener('click', function() {
axios.get('https://jsonplaceholder.typicode.com/todos/1')
.then(response => {
document.getElementById('result').innerText = `제목: ${response.data.title}`;
})
.catch(error => console.error('Error:', error)); // 오류 처리
});
</script>
"Promise 기반이다"
"Promise 기반이다"라는 표현은 JS에서 비동기 작업을 처리하는 데에 Promise 객체가 사용된다는 의미이다. Promise는 비동기 작업이 완료된 후에 결과를 처리하는 방법을 제공하는 객체로, 콜백 함수의 중첩을 줄이고, 코드의 가독성을 높이는 데 큰 도움이 된다.
"Promise가 객체?"
"Promise가 객체"라고 할 때, '객체'는 프로그래밍에서 데이터와 동작을 캡술화한 구조체이다. JS에서 객체는 속성과 메서드를 포함할 수 있는 데이터 구조를 의미한다.
Promise도 마찬가지로 이러한 객체의 일종이다. 그러나 '객체'라고 표현하는 것은 Promise가 단순한 데이터 객체가 아니라 특정한 구조와 동작 방식을 따르는 특별한 객체이기 때문이다.
Promise의 형태가 특별한 이유
1. 구조적 특징 :
- Promise는 비동기 작업을 추상화하여 그 상태를 관리하는 데 필요한 기능들을 제공한다.
- 이 기능들은 특정 메서드(`.then()`, `.catch()`, `.finally()`)를 통해 접근할 수 있다.
2. 상태 관리 :
- Promise는 세 가지 상태(Pending, Fulfilled, Rejected)를 가진다.
- 이 상태는 비동기 작업의 현재 진행 상태를 나타내며, Promise 객체는 이 상태에 따른 동작을 수행한다.
3. 동작 방식 :
- Promise는 주어진 비동기 작업이 완료되면 자동으로 상태를 변경하고, 그에 따라 등록된 콜백함수를 호출한다.
- 이 동작 방식은 일반 객체와 다르게 Promise가 비동기 작업을 처리하는 특별한 패턴을 제공한다는 것을 의미한다.
4. 체인 가능성 :
- Promise는 `.then()` 메서드를 통해 여러 비동기 작업을 체인으로 연결하여 실행할 수 있게 한다.
- 이는 일반 객체서는 볼 수 없는 Promise만의 중요한 특징이다.
Promise는 비동기 코드를 보다 읽기 쉽고 유지 보수하기 쉽게 만드는 디자인 패턴의 일환이다. 이는 프로미스가 단순히 데이터를 저장하는 객체가 아니라, 특정한 규약과 패턴을 따르는 "형태"라는 점을 강조하기 위해 "형태"라는 표현을 사용한다.
const examplePromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve('Success!');
} else {
reject('Error!');
}
}, 1000);
});
examplePromise
.then((message) => {
console.log(message); // Success!
})
.catch((error) => {
console.log(error);
});
여기서 Promise는 단순히 데이터 구조가 아니라, 비동기 작업을 관리하고 체인으로 처리하는 데 필요한 모든 메커니즘을 갖춘 구조를 가지고 있다. 따라서 '형태'라는 표현은 Promise의 특수한 기능과 구조적 특성을 강조하기 위한 것이다.
AJAX요청을 할 때 자주 보게 되는 에러가 있는데 바로 CORS 관련 에러이다.
이 에러가 발생하는 이유는 서로 다른 도메인/포트의 서버로 요청이 갈 때 브라우저에서 발생한다.
예를 들어, naver.com에서 kakao.com으로 데이터를 요청할 때이다.
해결 방법
1. 프록시 방식 : 브라우저에서 프론트서버로 요청 > 프론트서버에서 백엔드서버로 요청 시
프론트에서 요청 header에 Access-Control-Allow-Origin:"*" 이런 걸 추가하거나 CORS 정책 관련 기능을 끈다.
2. 프론트서버 cors 설정 : npm i cors 설치 후 server.js에서 미들웨어 cors를 추가하여 주면, 자동으로 모든 요청의 header에 Access-Control-Allow-Origin 옵션이 추가되어진다.
app.use(cors({
origin : '*', // 모든 요청 허용
origin : true, // 들어오는 요청 도메인/포트가 자동으로 origin에 삽입된다.
origin : 'www.domain.com', // 실 서비스에서는 실제 서비스 도메인을 넣어. 해당 도메인 요청만 허용한다.
credentials : false, // 개발단계에서는 false, 실 서비스에서는 true
})
'Javascript' 카테고리의 다른 글
개발자 90%가 잊고 사는 자바스크립트 동작원리 (0) | 2025.04.23 |
---|---|
FormData 객체란? (0) | 2024.04.04 |
DOM 조작할 때 사용되는 몇 가지 사이즈 속성들 (1) | 2024.02.26 |
화살표 함수와 객체 반환에 대해서 (0) | 2023.12.15 |
클로저(Closure) (0) | 2023.11.30 |