XMLHttpRequest와 fetch() 의 차이점과 fetch() 자세히 살펴보기

kyeongboo·2023년 4월 26일

XMLHttpRequest와 fetch() 가장 큰 차이점은?

우선 XMLHttpRequest가 무엇인지 Fetch API가 무엇인지 먼저 살펴보자면

XMLHttpRequest란?

XMLHttpRequest객체를 이용해서 JavaScript에서 서버에 동기 또는 비동기식 요청을 보낼 수 있으며 요청에 대한 응답 정보를 웹페이지에서 로드할 수 있습니다. 따라서 웹페이지를 다시 로드하지 않아도 웹페이지의 일부만 변경할 수 있습니다.

XMLHttpRequest 사용방법

1. XMLHttpRequest 객체를 생성합니다.
2. open()메서드로 요청에 필요한 정보를 설정합니다.
3. send()메서드로 서버에 요청을 보냅니다.
4. 응답에 대한 콜백 함수를 생성합니다.

다음 코드의 의미를 알아보아요.

// 1. XMLHttpRequest 객체를 생성합니다.
const requestObj = new XMLHttpRequest();
// 2. open()메서드로 요청에 필요한 정보를 설정합니다. 요청을 초기화하고, 통신방법과 요청을 발신할 대상의 주소를 전달합니다.
requestObj.open('GET', 'url');
// onreadystatechange 프로퍼티는 XMLHttpRequest 객체의 readyState 프로퍼티 값이 변할 때마다 자동으로 호출되는 함수입니다.
requestObj.onreadystatechange = () => { // readystate 가 변화하면 실행되는 이벤트리스너 입니다.
	// readystate : 요청을 보내는 클라이언트의 상태를 의미합니다.
    // readystate의 종류
    // 0 (UNSENT) - XHR 객체가 생성되었지만 아직 초기화되지 않았습니다.
    // 1 (OPENED) - open()함수가 호출되어 요청이 초기화되었습니다.
    // 2 (HEADERS_RECEIVED) - send()함수가 호출되었습니다.
    // 3 (LOADING) - 데이터를 다운받는 중 입니다.
    // 4 (DONE) - 통신이 완료되었습니다.
   
   
   // readyState 프로퍼티는 XMLHttpRequest 객체의 현재 상태입니다.
   // requestObj.readyState === 4 : 데이터를 전부 받은 상태라는 의입니다.
   
   // status는 서버의 문서 상태입니다.
   // requestObj.status === 200 : 서버로부터 응답상태가 요청에 성공하였다는 의미입니다.
    if (requestObj.readyState == 4 && requestObj.status == "200") {

   // responseText : 서버에 요청하여 응답으로 받은 데이터를 문자열로 반환합니다.
        const result = requestObj.responseText;

    }
};
// 3. send()메서드로 서버에 요청을 보냅니다.send 메소드가 실행되어야만 우리가 위에서 설정한 내용들이 의미를 가지게 됩니다.
requestObj.send();

더보기

값(status)텍스트(statusText)설명
200OK요청 성공
403Forbidden접근 거부
404Not Found페이지 없음
500Internal Server Error서버 오류 발생

하지만 XMLHttpRequest API로 통신을 주고 받을 당시 큰 번거로움을 느끼고 JQuery를 통해 구현하기 시작하다가 이후 fetch API가 ES6표준으로 등장하면서 fetch API를 통해 통신하는것이 주요방식으로 자리를 잡았습니다.

그렇다면 다시 질문으로 돌아와서 XMLHttpRequest와 fetch()의 가장 큰 차이점은 뭘까요?

XMLHttpRequest

fetch()

바로 XMLHttpRequest생성하는 인스턴스는 통신 기능을 수행하는 XMLHttpReques 객체를 반환하지만 Fetch API인스턴스를 만들지 않고 대신 Promise를 반환한다는 것입니다.

그렇다면 fetch()는 어떻게 사용할까요?

let result = fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json');
console.log(result);

원하는 url을 fetch() 인자로 넣어준 뒤 그 값을 json형태로 변환시켜 넘겨주면 이 값을 다룰 수 있게 됩니다.

XMLHttpRequest 객체보다 훨씬 간단한 방법으로 데이터를 가져오는데요.

fetch()는 기본적으로 다음과 같이

const promise = fetch(resource, [option])

fetch는 2개의 매개변수를 가집니다.

  • 첫번째 매개변수 : 필수사항, HTTP요청을 보낼 URL
  • 두번째 매개변수 : 선택사항, method, headers, body 등

만약 두번째 매개변수를 입력하지 않는다면 default 값으로 GET메서드 데이터 요청이 전송됩니다.

또한 fetch()가 반환하는 promise는 네트워크 장애 및 요청 실패 시(서버가 개입되지 못한 경우)만 rejected 상태이고 나머지는 fullfilled 상태입니다.
만약 404, 500 등 오류를 수신하게 된다면 Response 객체의 ok 속성false가 되고 나머지 상황은 true가 된다.

그리고 Promise인 전달받은 Response 객체를 통해서 실제 데이터를 받을 수 있습니다.

응답 몸체에 담긴 데이터는 사용자가 원하는 형태로 파싱하여 접근할 수 있는데 여기에는 대표적으로 JSON 형태로 반환하는 response.json()과 텍스트 형태로 반환하는 response.text() 메서드들이 있습니다.

fetch() 활용

get 방식

const url = "https://jsonplaceholder.typicode.com/posts/1";
const byFetch = () => {
  fetch(url1)
  // 응답 처리 1단계: 상태만 파악 가능
  .then.((response) => {
    if(!response.ok) {
      throw new Error(`오류 발생: ${response.status}`);
    }
    return response.json(); // 응답은 native js 객체로 변환
    // 응답 처리 2단계 실제 데이터 활용
    .then((json) => console.log(json))
    .catch((error) => console.log.error("fetch fail",error));

fetch()를 활용하게 간단하게 코드를 만들어보았습니다.

        class UserStorage {

            // 유저가 등록되었는지 확인
            searchUser(userName, password) {

                return new Promise((resolve, reject) => {

                    const xhr = new XMLHttpRequest();
                    xhr.open('GET', 'users.json');
                    xhr.onreadystatechange = () => {
                        if (xhr.readyState === 4 && xhr.status === 200) {

                            const result = JSON.parse(xhr.responseText).user.find((item) => {
                                return item.userName === userName && item.password === password
                            });

                            if (result) {
                                resolve(userName);
                                // onSuccess(userName);
                            } else {
                                reject('user not found');
                                // onError(new Error('user not found'));
                            }
                        }
                    }

                    xhr.send();
                })
            }
profile
적극성과 커뮤니케이션 능력이 겸비된 개발자로 성장하자!

0개의 댓글