Post

[JavaScript] 비동기 통신 웹 개발 기법에 대해서 _ AJAX & XHR

AJAX (Asynchronous JavaScript and XML)에 대해서

‘AJAX’는 웹 페이지가 서버와 비동기적으로 데이터를 교환할 수 있게 해주는 개발 기법이다. ‘AJAX’는 여러 기술의 조합을 포함하는데, 이 중 하나가 바로 ‘XMLHttpRequest’ 객체이다. ‘AJAX’를 사용하면 웹페이지 전체를 다시 로드하지 않고도 서버로부터 데이터를 받아와 페이지의 특정 부분만을 업데이트할 수 있다.

특징

  1. 비동기성(Asynchronous): AJAX의 핵심은 비동기적 통신이다. 전통적인 웹 페이지는 사용자가 요청을 하면 페이지 전체를 다시 로드해야 했습니다. 그러나 AJAX를 사용하면, 웹 페이지의 전체를 다시 로드할 필요 없이 필요한 데이터만 서버로부터 받아올 수 있다.
  2. JavaScript와 XMLHttpRequest 객체: AJAX는 JavaScript를 사용하여 작동합니다. JavaScript는 웹 페이지에서 XMLHttpRequest 객체를 생성하고, 이 객체를 사용하여 서버에 데이터를 요청한다. 서버는 요청된 데이터를 JavaScript로 다시 보내고, JavaScript는 이 데이터를 사용하여 웹 페이지를 동적으로 업데이트 한다.
  3. 데이터 형식: 초기 AJAX는 XML형식의 데이터를 사용했지만, 현재는 JSON(JavaScript Object Notation)이 더 널리 사용된다. JSON은 웹 환경에서 데이터를 교환하기에 더 가볍고, JavaScript와의 호환성도 뛰어나다.

XHR (XMLHttpRequest)에 대해서

XHR은 웹 브라우저에서 제공하는 API의 일종으로, JavaScript를 통해 서버와 비동기적으로 데이터를 주고받을 수 있게 해주는 객체이다. 이 기능은 웹 페이지가 서버에 데이터를 요청하고, 받아온 데이터로 페이지의 일부를 업데이트할 수 있게 해주어, 웹 애플리케이션의 사용성과 반응성을 크게 향상시킨다.

요청 및 응답 처리

XHR을 사용하면, 서버에 HTTP 요청을 보내고 응답을 받을 수 있다. 개발자는 이 객체를 사용하여 요청의 종류(GET, POST 등), 요청할 URL, 전송할 데이터 등을 지정할 수 있으며, 서버로 부터 응답을 처리하는 코드를 작성할 수 있다.

요청의 종류

요청설명
GET데이터를 읽거나 검색
POST새로운 리소스를 생성
PUT리소스를 생성/업데이트
PATCH리소스의 일부를 업데이트
DELETE리소스를 삭제
OPTION서버에 적용된 통신 옵션을 요청

요청 및 응답 처리 과정 예제

1
let xhr = new XMLHttpRequest();

XHR 객체 생성: 웹 페이지의 JavaScript에서 XMLHttpRequest 객체를 생성한다. 해당 객체는 서버와의 통신을 담당한다.

1
xhr.open("GET", "https://hello.com/api", true);

요청의 초기화: 생성된 XHR 객체를 사용하여 서버에 보낼 HTTP 요청을 초기화한다. 이때, 요청의 종류, 요청할 URL, 비동기 여부 등을 지정한다.

1
2
3
4
5
6
7
8
9
10
11
xhr.onreadystatechange = function () {
  if (xhr.readyState == XMLHttpRequest.DONE) {
    if (xhr.status == 200) {
      // 요청 성공, 응답 처리
      console.log(xhr.responseText);
    } else {
      // 에러 처리
      console.log("Request failed");
    }
  }
};

이벤트 핸들러 설정: 서버로부터 응답이 도착하면 실행될 이벤트 핸드러를 설정한다. 가장 일반적인 핸들러는 ‘onreadystatechange’이벤트 핸들러로, 요청의 상태가 변할 때마다 실행된다.

1
xhr.send();

요청 전송: 설정된 요청을 서버로 전송한다. GET요청의 경우 URL에 모든 정보가 담겨 있으므로, ‘send’메소드에는 별도의 데이터를 전달하지 않는다. POST 요청의 경우, ‘send’메소드에 데이터를 포함시킬 수 있다.

1
let responseData = JSON.parse(xhr.responseText);

응답 처리: 서버로부터 응답이 도착하면, 설정된 이벤트 핸들러가 작동한다. 응답은 ‘xhr.responseText’ 또는 ‘xhr.responseXML’을 통해 접근할 수 있다. JSON 형태의 응답을 처리할 때는 응답 텍스트를 JavaScript 객체로 변환하는 것이 일반적이다.

이벤트 처리

XHR은 여러 종류의 이벤트를 처리할 수 있다. 예를 들어, 요청의 상태가 변할 때마다 발생하는 이벤트를 감지하여, 데이터 로딩의 시작과 끝, 오류 발생 등을 사용자에게 알릴 수 있다.

onreadystatechange: 이벤트 처리기

해당 핸들러는 XMLHttpRequest의 readyState속성이 변할 때마다 호출된다. ‘readyState’는 요청의 현재 상태를 나타낸다.

readyState

  • 0 _ UNSENT: 요청이 초기화되지 않음 (open 메소드가 아직 호출되지 않음)
  • 1 _ OPENED: 서버와의 연결이 설정됨 (open 메소드가 호출됨)
  • 2 _ HEADERS_RECEIVED: 요청이 서버에 전송됨 (send 메소드가 호출됨)
  • 3 _ LOADING: 서버가 요청을 처리 중임 (응답의 일부를 받고 있음)
  • 4 _ DONE: 요청 처리가 완료되고, 응답이 준비됨
1
2
3
4
5
6
7
8
9
xhr.onreadystatechange = function () {
  if (xhr.readyState == XMLHttpRequest.DONE) {
    if (xhr.status == 200) {
      // 성공적인 응답 처리
    } else {
      // 에러 처리
    }
  }
};

onload

요청이 성공적으로 완료되었을 때 호출된다. ‘onreadystatechange’와 달리 모든 응답 데이터가 도착했을 때 한 번만 호출된다. 주로 데이터 로딩이 완료된 후 처리를 단순화하기 위해 사용된다.

1
2
3
xhr.onload = function () {
  // 성공적인 응답 처리
};

onerror

요청 중 네트워크 오류 등으로 에러가 발생했을 때 호출된다. 이 핸들러는 오류의 원인에 대해 자세한 정보는 제공하지 않지만, 요청이 실패했음을 알려준다.

1
2
3
xhr.onerror = function () {
  // 에러 처리
};

onprogress

데이터가 전송되는 동안 주기적으로 호출된다. 이 핸들러를 사용하면 데이터 로딩의 진행 상태를 사용자에게 표시할 수 있다. 예를 들어, 진행률 표시줄을 업데이트 하는 데 사용할 수 있다.

1
2
3
4
5
6
xhr.onprogress = function (event) {
  if (event.lengthComputable) {
    let percentComplete = (event.loaded / event.total) * 100;
    // 진행 상태 업데이트
  }
};

ontimeout

요청에 대한 응답이 설정된 시간 내에 오지 않았을 때 호출된다. 타임아웃은 ‘timeout’속성을 설정함으로써 정할 수 있다.

1
2
3
4
xhr.timeout = 2000;
xhr.ontimeout = function () {
  // 타임아웃 처리
};

보안 및 제한 사항

XHR은 동일 출처 정책(Same-Origin Policy)을 따른다. 이는 보안상의 이유로, XHR을 사용한 요청은 기본적으로 현재 페이지와 동일한 도메인에만 보낼 수 있다는 것을 의미한다. 다른 도메인으로의 요청을 하려면 CORS(Cross-Origin Resource Sharing)등의 방법을 사용해야 한다.

마무리 하며, 데이터 요청 및 웹페이지 표시 예제

1
<div id="data-container"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 객체 생성 및 요청 설정
let xhr = new XMLHttpRequest();
xhr.open("GET", "https://example.com/data", true);

// 응답 처리를 위한 이벤트 핸들러 설정
xhr.onreadystatechange = function () {
  if (xhr.readyState == XMLHttpRequest.DONE) {
    if (xhr.status == 200) {
      let data = xhr.responseText;
      document.getElementById("data-container").innerHTML = data;
    } else {
      console.log("Request failed");
    }
  }
};

// 요청 전송
xhr.send();
This post is licensed under CC BY 4.0 by the author.

© chanho. Some rights reserved.