Ajax VS XMLHttpRequest VS fetch

박민우·2023년 10월 6일
1

JavaScript

목록 보기
10/14
post-thumbnail

HTTP 통신, 비동기처리를 공부하다보면 Ajax, XMLHttpRequest, fetch API 같은 단어들이 등장한다. 비슷한 듯 다른 이들이 각각 어떤 의미를 갖는지, 공통점과 차이점은 무엇인지 알아보자 !


📌 Ajax

Ajax란 JS를 사용하여 브라우저가 서버에게 비동기 방식으로 데이터를 요청하고, 서버가 응답한 데이터를 수신하여 웹 페이지를 동적으로 갱신하는 프로그래밍 방식을 말한다.

Ajax는 브라우저에서 제공하는 Web API인 XMLHttpRequest 객체를 기반으로 동작한다.

Ajax 이전의 웹 페이지는 html 태그로 시작해서 html 태그로 끝나는 완전한 HTML을 서버로부터 전송받아 웹 페이지 전체를 처음부터 다시 렌더링하는 방식으로 동작했다. 따라서 화면이 전환되면 서버로부터 새로운 HTML을 전송받아 웹 페이지 전체를 처음부터 다시 렌더링했다.

이러한 전통적인 방식의 단점

  1. 불필요한 데이터 통신 => 변경할 필요가 없는 부분까지 포함된 HTML파일을 매번 다시 전송받음
  2. 불필요한 렌더링 => 변경할 필요가 없는 부분까지 다시 렌더링, 이로 인해 화면 전환이 일어나 화면이 깜빡이기도 함
  3. 블로킹 => 서버와의 통신이 동기 방식으로 동작하기 때문에 서버로부터 응답을 받기 전까지 다음 처리가 블로킹 됨.

하지만 Ajax를 사용함으로써,

웹 페이지의 변경에 필요한 데이터만 비동기 방식으로 전송 받아 변경할 필요가 있는 부분만 한정적으로 렌더링하는 것이 가능해졌다. 이를 통해 브라우저에서도 데스크톱 애플리케이션과 유사한 빠른 퍼포먼스와 부드러운 화면 전환이 가능해졌다.

SPA를 의미하는 것 같다,,,!


📌 XMLHttpRequest

브라우저는

  • 주소창
  • a 태그
  • form 태그

등을 통해 HTTP 요청 전송 기능을 기본적으로 제공하고, JS를 통해 HTTP 요청을 전송하려면 XMLHttpRequest 객체를 사용한다. Web API인 XMLHttpRequest 객체는 HTTP 요청 전송과 HTTP 응답 수신을 위한 다양한 메서드와 프로퍼티를 제공한다.


Web API인 XMLHttpRequest 객체가 제공하는 다양한 메서드와 프로퍼티를 사용해

  • XMLHttpRequest 객체를 생성하고
  • HTTP 요청을 초기화 하고
  • HTTP 요청 헤더를 설정하고
  • HTTP 요청을 전송할 수 있다.

XMLHttpRequest 객체를 이용한 HTTP 통신 예시

서버가 전송한 응답을 처리하려면 XMLHttpRequest 객체가 발생하는 이벤트를 캐치해야한다.

객체가 가지는 이벤트 핸들러 프로퍼티 중, HTTP 요청의 현재 상태를 나타내는 readyState 프로퍼티 값이 변경된 경우 발생하는 readystatechange 이벤트를 캐치하여 HTTP 응답을 처리할 수 있다.

XMLHttpRequest 객체는 브라우저에서 제공하는 Web API이므로 반드시 브라우저 환경에서 실행해야 한다.

const xhr = new XMLHttpRequest(); // XMLHttpRequest 객체 생성
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1'); // HTTP 요청 초기화
xhr.setRequestHeader('content-type','application/json'); // HTTP 요청 헤더 설정
xhr.send(); // HTTP 요청 전송

Xhr.onreadystatechange = () => {
    if(xhr.readyState !== XMLHttpRequest.DONE) return;
    
    if(xhr.status === 200){
        console.log(JSON.parse(xhr.response));
    }else{
        console.log('ERROR', xhr.status, xhr.statusText);
    }
}

Xhr.onreadystatechange = () => { }

=> readystatechange 이벤트는 HTTP 요청의 현재 상태를 나타내는 readyState 프로퍼티가 변경될 때마다 발생한다.


if(xhr.readyState !== XMLHttpRequest.DONE) return;

=> readyState 프로퍼티값이 4(DONE)가 아니면 서버응답이 완료되지 않은 상태이다.


if(xhr.status === 200){ }

status 프로퍼티는 응답 상태 코드를 나타내며, 값이 200이라면 정상적인 응답을 나타낸다.


📌 fetch

fetch 함수는 XMLHttpRequest 객체와 마찬가지로 HTTP 요청 전송 기능을 제공하는 클라이언트 사이드 Web API로, XMLHttpRequest를 대체하기 위해 도입된 최신 표준 웹 API이다.

fetch 함수는 XMLHttpRequest 객체보다 사용법이 간단하고 프로미스를 지원하기 때문에 비동기 처리를 위한 콜백 패턴의 단점을 해결할 수 있다.

Ajax는 개념적으로 비동기 통신을 위한 패러다임을 가리키며, XMLHttpRequest와 fetch는 실제로 이를 구현하는 기술이다.

fetch 함수 기본 사용법

fetch('baseURL/todos/1')
	.then(response => console.log(response));

fetch 함수는 HTTP 응답을 나타내는 Response 객체를 래핑한 Promise 객체를 반환한다. 따라서 후속 처리 메서드 then을 통해 프로미스가 resolve한 Response 객체를 전달받을 수 있다.

fetch 함수 에러 처리

fetch 함수를 사용할 때는 에러 처리에 주의해야 한다.

const wrongURL = '잘못된 url';

fetch(wrongURL)
	.then(()=>console.log('ok'))
	.catch(()=>console.log('error'));

잘못된 url이 지정되었기 때문에 404 not found 에러가 발생하고 catch 후속 처리 메서드에 의해 error가 출력될 것 같지만 실제로는 ok가 출력된다.

fetch 함수가 반환하는 프로미스는 기본적으로 404 not found나 500 Internal Server Error와 같은 HTTP 에러가 발생해도 에러를 reject하지 않고 불리언 타입의 ok 상태를 false로 설정한 Response 객체를 resolve한다.

오프라인 등의 네트워크 장애나 CORS 에러에 의해 요청이 완료되지 못한 경우에만 프로미스를 reject한다.


따라서, fetch 함수를 사용할 때는 다음과 같이 response의 ok 상태를 확인해 명시적으로 에러를 처리할 필요가 있다.

const wrongURL = '잘못된 url';

fetch(wrongURL)
	.then(response => {
    	if(!response.ok) throw new Error(response.statusText);
    	return response.json();
	})
	.then(todo => console.log(todo))
	.catch(err => console)

📌 Ajax vs XMLHttpRequest vs fetch

  • Ajax는 개념적으로 비동기 통신을 위한 패러다임을 가리키며, XMLHttpRequest와 fetch는 실제로 이를 구현하는 기술이다.

  • XMLHttpRequest는 오래된 기술이고, 비교적 복잡하며 가독성이 낮다. fetch는 더 간결하고 현대적인 API를 제공한다.

  • XMLHttpRequest는 기본적으로 콜백 기반의 처리 방식을 사용하며, fetch는 Promises와 함께 사용하여 더 편리한 비동기 코드 작성을 지원한다.

=> 정리하면, Ajax는 비동기 통신의 개념을 가리키며, XMLHttpRequest와 fetch는 이 개념을 실제로 구현하는 기술이다. 최근에는 fetch를 사용하는 것이 더 효과적이고 권장된다.


🙇🏻‍♂️ 참고

모던 자바스크립트 Deep Dive

profile
꾸준히, 깊게

0개의 댓글