XHR
XMLHttpRequest
비동기 HTTP 요청 API. Ajax 기반. Fetch API로 대체 중.
XMLHttpRequest
비동기 HTTP 요청 API. Ajax 기반. Fetch API로 대체 중.
XHR(XMLHttpRequest)은 JavaScript에서 서버와 비동기 HTTP 통신을 수행하는 API입니다. 1999년 Microsoft가 Outlook Web Access를 위해 처음 개발했으며, 이후 모든 브라우저의 표준이 되었습니다.
XHR은 Ajax(Asynchronous JavaScript and XML)의 핵심 기술로, 페이지 새로고침 없이 서버와 데이터를 주고받을 수 있게 합니다. Gmail, Google Maps 등 Web 2.0 시대의 인터랙티브 웹 애플리케이션을 가능하게 한 기술입니다.
현재는 더 현대적인 Fetch API가 권장되지만, XHR은 진행률 추적, 요청 취소 등 일부 기능에서 여전히 사용됩니다.
기본 GET 요청
// XHR 객체 생성
const xhr = new XMLHttpRequest();
// 요청 초기화 (메서드, URL, 비동기 여부)
xhr.open('GET', '/api/users', true);
// 응답 처리
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log(data);
} else {
console.error('요청 실패:', xhr.status);
}
}
};
// 요청 전송
xhr.send();
POST 요청 (JSON 데이터)
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/users', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status === 201) {
console.log('생성 성공:', JSON.parse(xhr.response));
}
};
const userData = { name: '홍길동', email: 'hong@example.com' };
xhr.send(JSON.stringify(userData));
파일 업로드와 진행률 추적
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/upload', true);
// 업로드 진행률
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
const percent = (e.loaded / e.total) * 100;
console.log(`업로드: ${percent.toFixed(1)}%`);
}
};
// 완료 처리
xhr.onload = () => console.log('업로드 완료');
xhr.onerror = () => console.error('업로드 실패');
const formData = new FormData();
formData.append('file', fileInput.files[0]);
xhr.send(formData);
팀장
"이 레거시 코드 XHR로 되어 있는데, Fetch로 마이그레이션 해야 하나?"
개발자
"대부분은 Fetch가 좋은데요, 파일 업로드 진행률 표시하는 부분은 XHR이 더 편해요. upload.onprogress 이벤트가 Fetch에는 없거든요."
팀장
"그럼 업로드 부분만 XHR 유지하고 나머지는 Fetch로 바꾸자."
readyState 상태 값 이해
0: UNSENT, 1: OPENED, 2: HEADERS_RECEIVED, 3: LOADING, 4: DONE. status 확인은 readyState가 4일 때만 의미있습니다.
동기 요청 지양
xhr.open(method, url, false)로 동기 요청 가능하지만, UI를 블로킹하므로 절대 사용하지 마세요. 브라우저에서 경고가 표시됩니다.
CORS 이슈
다른 도메인 요청 시 서버에서 CORS 헤더 설정이 필요합니다. withCredentials = true로 쿠키 포함 요청도 가능합니다.