본문 바로가기

Dev/[Javascript]

[Javascript] XMLHttpRequest와 Ajax에 대한 이야기

반응형

 

 

0. 의문의 시작

최근 같은 전공의 대학 동기들을 만나 술자리를 가지던 중 Ajax와 XMLHttpRequest에 대한 대화를 나누게 되었고, 아래 내용에 대해선 모두 의견의 차이가 없었다.

  • Ajax 는 비동기 통신을 위한 하나의 '프로그래밍 기법'이며, javascript 진영에서는 이 기법을 구현하기 위해 XMLHttpRequest를 사용한다.
  • 이 기법과 DOM API를 사용하여 화면 전체를 다시 그리지 않아도 된다.
  • XMLHttpRequest는 HTTP 프로토콜을 사용하여 서버와 통신한다.

그러나 아래 대화까지 도달했을 때, 모두 제대로 설명할 수 있는 사람이 없었다.

  • XMLHttpRequest의 원리?
  • 언어 레벨과 프로토콜 레벨 사이에, 이것을 실행시켜주는 것은 무엇?

결국 다음과 같은 결론을 내고 대화는 마무리가 되었다.

  • XMLHttpRequest 객체를 브라우저나 Node.js와 같은 엔진(런타임)이 실행한다

집에 와서도 찜찜함이 남아있어 해당 내용을 좀 더 세부적으로 공부해야겠다는 생각이 들어 이 포스팅을 적게 되었다.

 

1. 그래서 정답은 무엇인가

- 비동기 통신을 위한 XMLHttpRequest는 브라우저 내 내장된 자바스크립트 엔진에 의해 실행되며, HTTP 프로토콜로 변환되어 서버로 전송된다. 

- 결국 브라우저의 내장 API에 대한 지식이 부족했던 것.

크롬 개발자 도구에서 호출해 본 XMLHttpRequst 객체

- Node.js에서 실행되는 Javascript의 경우, XMLHttpRequest 를 지원하지는 않고 http, request, axios와 같은 모듈을 별도로 설치하여 이와 같은 역할을 수행할 수 있다.

 

 

2. XMLHttpRequest 와 Ajax에 대하여

Ajax는 XMLHttpRequest 를 wrapping한 별도의 라이브러리?

- Ajax를 일부 주니어 개발자들은 'XMLHttpRequest 를 wrapping한 별도의 라이브러리'라고 생각하고 있지만, 이는 틀린말이다.

- 아마 JQuery의 $.ajax를 사용하다보니 그렇게 생각할 수 있다.

- JQuery의 github를 보면 JQuery.ajax()는 XMLHttpRequest 를 wrapping했다는 말이 맞지만 이는 JQuery.ajax()이지 Ajax가 아니다.

jquery git을 보면 ajax 관련 소스코드에서 XMLHttpRequest 객체를 자주 볼 수 있다.

 

- Ajax는 라이브러리나 프레임워크가 아닌, 서버와 비동기 통신하기 위한 프로그래밍 기법이다.

- 그래서 이 기법을 꼭 XMLHttpRequest를 사용하여 구현할 필요는 없다.

// fetch()를 사용한 Ajax 프로그래밍 예제
fetch('https://example.com/data.json')
  .then(response => response.json())
  .then(data => {
    // 데이터를 화면에 표시하는 로직
    console.log(data);
  })
  .catch(error => {
    console.error('데이터 가져오기 실패:', error);
  });

 

 

XMLHttpRequest말고도 Web Browser에 내장되어있는 API 종류들?

- 아래와 같은 내장 API들이 존재한다.

1. canvas - javascript 및 HTML을 통해 그래픽 요소를 그리는 데 사용되며 주로 2D 그래픽을 다룬다.

2. Storage, Cookie - 브라우저 내 할당 된 메모리나 접속한 클라이언트의 하드디스크 등에 저장된다.

3. DOM API - HTML형태로 작성된 내용을 객체로 표현해주고, 이를 조작한다.

4. Fetch API : XMLHttpRequest 대신 사용할 수 있는 새로운 API로, Promise를 이용하여 데이터를 주고받는 기능을 제공.

5. Web Workers : 백그라운드 스레드에서 JavaScript 코드를 실행 가능하도록 함.

6. Web Socket : 실시간 양방향 통신을 지원하는 기능 제공.

 

- 이 외에도 정말 다양한 API들을 제공한다. 확인하고 싶으면 아래 페이지를 접속해보면 된다.

https://developer.mozilla.org/en-US/docs/Web/API

 

Web APIs | MDN

When writing code for the Web, there are a large number of Web APIs available. Below is a list of all the APIs and interfaces (object types) that you may be able to use while developing your Web app or site.

developer.mozilla.org

- 또한 WebRTC API의 경우 Chrome Firefox에서는 거의 완전히 동일한 기능을 제공하지만, Safari에서는 일부 기능이 제한되는 등 웹 브라우저들마다 세부적으로 동작하는 방식이 다르고, 지원하는 API목록도 다를 수 있다.

- 아래는 fetch API를 지원하지 않는 오래 된 브라우저에서도 서버와 통신하기 위해 코드를 분기처리하는 간략한 예제이다.

if (window.fetch) {
  // fetch API 사용
  fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));
} else {
  // XHR 객체 사용
  const xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://api.example.com/data');
  xhr.onload = () => {
    if (xhr.status === 200) {
      console.log(xhr.responseText);
    } else {
      console.error('Error!', xhr.statusText);
    }
  };
  xhr.onerror = () => console.error('Error!');
  xhr.

- 이렇게 매번 분기처리를 하기에는 번거로우므로 babel, polyfill등을 사용하여 오래 된 브라우저와 모던 브라우저 간 동작성을 같게 한다.

- 대부분의 Browser는 웹 표준을 지키면서 개발되고 업데이트되므로, 개발에 필요한 API들은 대부분 사용하는 방식이 비슷하다.

 

 

Ajax 덕분에 화면 전체를 새로 렌더링하지 않아도 된다?

- 내 생각에는 틀린 말이다.

- 정확히 말하면, DOM API 덕분에 화면 전체를 렌더링하지 않아도 되는것이다.

// DOM API를 사용한 화면 일부 업데이트
document.getElementById('update-button').addEventListener('click', function() {
  var container = document.getElementById('container');
  var paragraph = container.getElementsByTagName('p')[0];
  
  // 새로운 텍스트를 생성하여 화면에 업데이트
  var newText = document.createTextNode('화면이 업데이트 되었습니다.');
  paragraph.replaceChild(newText, paragraph.firstChild);
});

- 그러면 왜 Ajax 덕분에 화면 전체를 새로 렌더링하지 않아도 된다는 말이 나왔을까?

- 그건 아마도 아래와 같은 이유일 듯 싶다.

1. XMLHttpRequest와 같이 '다양한 형태의 데이터를 응답으로 받을 수 있는' 방법이 나오기 이전에는 요청을 보내면 응답으로 HTML 전체를 받는 형태로 동작하였고, 이 말은 곧 전체를 다시 렌더링한다는 의미이다. XMLHttpRequest는 XML 형식 뿐만 아니라 JSON을 포함한 대부분의 포맷으로 원하는 데이터만 응답으로 받을 수 있다.

2. Ajax와 같이 '비동기 통신'이 가능한 방법을 사용하지 않는다면(동기 통신으로 데이터를 받는다면) 요청을 보낸 뒤 응답이 오기 전까지 브라우저는 동작을 멈출 것이다. 그 후 브라우저 자체로 설정되어있는 Time-Out에 걸린다면, 결국 화면 전체를 새로 렌더링 해야하는 상황이 발생한다.

위 두 가지 이유로 'Ajax 덕분에 화면 전체를 렌더링하지 않아도 된다'는 말이 나온 것 같다.

 

 

전통적인 SSR과 모던 SSR의 차이

- 위에서 언급했듯이, XMLHttpRequest와 같은 원하는 포맷의 데이터를 받을 수 있는 방법이 나오기 이전에는 HTML 전체를 다시 받아와 렌더링하였다.

- 이는 곳 Server Side Rendering 방식이라는 말인데, 현대에도 React 진영의 Next.js, Vue.js 진영의 Nuxt.js 와 같은 SSR 프레임워크가 있고, SEO 등의 이유로 이를 선호하는 추세이다.

- 두 가지 SSR은 무엇이 다른것일까?

 

- 고전적인 Server Side Rendering에서는 서버에서 HTML 전체를 생성하여 브라우저에 전송한다.

- 브라우저는 HTML을 받으면 즉시 화면에 렌더링하고, 화면에 그려진 이후에 JavaScript 파일을 다운로드하고 실행한다.

- 이는 초기 로딩 속도가 빠르지만, 서버가 매번 전체 HTML을 생성하여 전송해야 하므로 서버 부하가 발생한다.

 

- 반면에 현대적인 Server Side Rendering에서는 서버에서는 HTML의 일부분과 필요한 JavaScript 파일을 전송하고(하이브리드 방식이라고도 한다), 브라우저는 JavaScript를 실행하여 화면을 완성한다.

- 이는 초기 로딩 속도가 상대적으로 느리지만, 클라이언트 측 JavaScript의 실행을 활용하여 서버의 부하를 줄일 수 있고, 필요한 부분만 변경되므로 사용자 경험 측면에서도 긍정적이다.

 

 

 

 

 

-퍼가실 때는 출처를 꼭 같이 적어서 올려주세요!

 

반응형