본문 바로가기
네트워크2

HTTP 요청/응답 (서버와 통신) :: XHR vs fetch vs Axios

by 로맨틱스터디 2025. 10. 4.
728x90
반응형

fetch, Axios, XMLHttpRequest(XHR)는

모두 HTTP 요청을 보내고 서버에서 응답을 받는 기능을 제공하지만,

 

사용 방식, 편의성, 기능 지원 여부에서 차이가 있어요. 단계별로 정리해볼게요.


1️⃣ 공통점

  • 모두 브라우저에서 서버로 요청(Request)을 보내고 응답(Response)을 받는 기능
  • GET, POST, PUT, DELETE 등 HTTP 메서드 지원
  • 헤더 설정 가능
  • 비동기 요청 가능

즉, 기능적으로는 **“서버와 통신”**이라는 같은 목적을 가지고 있어요.


2️⃣ 차이점 비교

항목 XMLHttpRequest (XHR) fetch Axios
문법 이벤트 기반
onload, onerror, onprogress
Promise 기반
.then(), await
Promise 기반
더 간결
비동기 지원 (true) 기본 비동기 기본 비동기
동기 지원 (false) – 거의 사용 X 불가 불가
업로드 진행률 지원 (xhr.upload.onprogress) 불가 지원 (onUploadProgress)
JSON 처리 수동 (JSON.parse(xhr.responseText)) 자동 지원 (response.json()) 자동 지원 (response.data)
브라우저 지원 오래된 브라우저까지 지원 최신 브라우저만 지원 최신 브라우저만 지원
요청 취소 복잡 AbortController 사용 CancelToken 사용 (편리)
편의성 낮음, 코드 길고 복잡 중간, Promise 기반으로 깔끔 높음, 에러 처리와 설정 편리

3️⃣ 특징 정리

XHR

  • 오래된 방식, 콜백 기반
  • 코드가 길고 복잡함

fetch

  • 모던한 브라우저 표준, Promise 기반
  • JSON 처리 등 편리, async/await와 자연스러운 연동
  • 네트워크 요청 취소는 AbortController 사용

Axios

  • fetch 위에서 만든 라이브러리
  • JSON 처리, 요청 취소, timeout, 업로드/다운로드 진행률 등 편리 기능 다수
  • 내부적으로 XHR 사용 → 업로드 진행률 등 XHR 기능 활용 가능
  • Promise/async/await 지원

4️⃣ 결론

  • 단순 HTTP 요청 → fetch
  • 실무 편의성과 기능 모두 → Axios
728x90

 

같은 POST 요청을 XHR, fetch, Axios로 구현한 예제를 만들어서 비교해볼게요.

 

가정: 서버 엔드포인트는 /api/data이고,

전송할 데이터는 { name: "Alice", age: 25 }입니다.


1️⃣ XMLHttpRequest (XHR)

const xhr = new XMLHttpRequest();
const url = "/api/data";
const data = JSON.stringify({ name: "Alice", age: 25 });

// 요청 설정
xhr.open("POST", url, true); // true = 비동기

// 헤더 설정
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");

// 응답 처리
xhr.onload = function () {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log("응답:", xhr.responseText);
  } else {
    console.error("에러:", xhr.status, xhr.statusText);
  }
};

// 요청 전송
xhr.send(data);

 

✅ 특징:

  • 콜백 기반
  • 업로드 진행률 표시 가능 (xhr.upload.onprogress)
  • JSON 처리 수동

2️⃣ fetch

 
const url = "/api/data";
const data = { name: "Alice", age: 25 };

fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
})
  .then(response => {
    if (!response.ok) throw new Error("네트워크 응답 에러");
    return response.json();
  })
  .then(result => console.log("응답:", result))
  .catch(err => console.error("에러:", err));

✅ 특징:

  • Promise 기반, async/await와 자연스럽게 사용 가능
  • JSON 자동 처리 가능 (response.json())
  • 업로드 진행률 이벤트는 지원 X
더보기

1️⃣ XMLHttpRequest

 
const xhr = new XMLHttpRequest();
  • XHR은 객체를 생성야 사용 가능
  • 즉, new XMLHttpRequest() → 새로운 요청 객체 생성 후 사용
  • 브라우저 내장 객체지만 매번 객체를 만들어야

2️⃣ Axios

 
import axios from "axios";
  • Axios는 라이브러리라서 브라우저/Node.js에 내장된 게 아님
  • 따라서 npm install axios 후 import해서 사용
  • 내부적으로 XHR을 사용해 HTTP 요청을 보내는 편의 기능 제공

3️⃣ fetch

 
fetch("/api/data")
  .then(res => res.json())
  .then(data => console.log(data));
  • fetch는 브라우저 내장 API
  • 객체 생성 필요 없음, 함수처럼 바로 호출 가능
  • 최신 브라우저에서는 기본 내장되어 있어 별도 import 없이 사용 가능
  • Node.js 환경에서는 별도 polyfill(예: node-fetch) 필요

🔹 정리

항목 XHR Axios fetch
객체 생성 필요 new XMLHttpRequest() ❌ 라이브러리 import ❌ 바로 호출 가능
내장 여부 브라우저 내장 라이브러리 필요 브라우저 내장
Promise 지원 콜백 기반
설치 필요 npm install ❌ 브라우저는 필요 없음

즉, fetch는 브라우저가 기본 제공하는 함수라서 new도, import도 필요 없고 바로 사용할 수 있는 거예요.


3️⃣ Axios

 
import axios from "axios";

const url = "/api/data";
const data = { name: "Alice", age: 25 };

axios.post(url, data)
  .then(response => {
    console.log("응답:", response.data);
  })
  .catch(err => {
    console.error("에러:", err);
  });

업로드 진행률 옵션 포함 예시

 
axios.post(url, data, {
  onUploadProgress: progressEvent => {
    const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
    console.log(`업로드 진행률: ${percent}%`);
  }
});

✅ 특징:

  • Promise 기반, async/await 가능
  • JSON 자동 처리 (response.data)
  • 업로드/다운로드 진행률 지원
  • 요청 취소, timeout 등 추가 기능 제공

 

1️⃣ 브라우저 내장 API와 Node.js 환경

  • 브라우저 내장 API = 브라우저가 기본으로 제공하는 기능
    • 예: fetch(), XMLHttpRequest, console.log(), document
    • 설치 필요 없음, 바로 사용 가능
  • Node.js에서는 브라우저 내장 API를 대부분 지원하지 않음
    • 예: Node.js에는 fetch가 최신 버전부터 내장되지만, 예전에는 node-fetch 같은 polyfill 필요
    • 브라우저 전용 APIdocument, window 등은 없음

즉, 브라우저 내장 API = 브라우저가 기본으로 제공하는 함수/객체


2️⃣ 라이브러리 설치 (예: Axios)

 
npm install axios
  • 이 명령어로 프로젝트 폴더 내 node_modules 디렉토리에 설치
  • 경로는 기본적으로 프로젝트 폴더에 자동 생성
  • 설치 위치를 바꾸고 싶으면 npm 옵션으로 지정 가능하지만, 대부분 프로젝트 내 node_modules 사용
  • 설치 후에는
 
import axios from "axios";
  • 이렇게 불러서 사용

3️⃣ new 키워드와 객체 생성

  • new = 새로운 객체를 만들 때 사용하는 연산자
  • 예:
 
const xhr = new XMLHttpRequest();
  • XMLHttpRequest라는 “설계도(클래스)”를 기반으로 **새로운 인스턴스(객체)**를 만드는 것
  • 이렇게 만들어진 xhr 객체 안에는 open, send, onload 같은 메서드와 속성이 들어 있음
  • 객체란 쉽게 말해 데이터 + 기능을 한 곳에 묶은 상자
 
const person = { name: "Alice", age: 25, greet() { console.log("Hi"); } };
  • 클래스/생성자 함수를 이용하면 new로 여러 객체를 손쉽게 만들 수 있음

4️⃣ 요약

개념 의미 예시
브라우저 내장 API 브라우저가 기본 제공하는 기능 fetch(), XMLHttpRequest
Node.js 내장 API Node.js가 기본 제공하는 기능 fs, http
라이브러리 설치 npm으로 프로젝트에 추가 npm install axios → import axios
new 클래스/생성자 함수로 새 객체 생성 const xhr = new XMLHttpRequest();

💡 핵심

  • 브라우저 내장 API → 설치 필요 없음, 바로 사용 가능
  • 라이브러리 → npm 설치 필요, 프로젝트 폴더 내 node_modules에 설치
  • new → 새로운 객체 생성
더보기

객체, 인스턴스, 클래스, 생성자 함수, new를 헷갈리지 않게 하나씩 정리해드릴게요.


1️⃣ 객체 vs 인스턴스

  • 객체(Object): 데이터를 담은 상자
const person = { name: "Alice", age: 25 };
  • 단순히 데이터를 담은 상자 → 일반 객체

 

  • 인스턴스(Instance): 클래스/생성자 함수를 기반으로 만들어진 객체
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

const p1 = new Person("Alice", 25);
const p2 = new Person("Bob", 30);
  • p1, p2 = Person 클래스인스턴스
  • 같은 “설계도”를 기반으로 만들어진 객체라 공통 구조/기능을 가능
     

정리:

  • 모든 인스턴스는 객체지만, 모든 객체가 인스턴스는 아님
  • 인스턴스라는 말을 쓰는 이유 → “이 객체는 특정 클래스/생성자 함수에서 만들어졌다”라고 명시하기 위해

2️⃣ 클래스(Class)와 생성자 함수(Constructor)

클래스(Class)

  • 객체를 쉽게 만들기 위한 설계도
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  greet() {
    console.log(`Hi, I'm ${this.name}`);
  }
}
 
  • 특징:
    • constructor() = 객체 초기화 함수
    • 메서드클래스 안에 정의 가능 → 모든 인스턴스가 공유

생성자 함수(Constructor Function) (ES5 이전 방식)

  • 클래스를 쓰기 전에는 함수로 객체 설계
 
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function() {
    console.log(`Hi, I'm ${this.name}`);
  };
}

const p1 = new Person("Alice", 25); // 인스턴스 생성

3️⃣ new 연산자

  • new = 클래스/생성자 함수 기반으로 새로운 인스턴스를 생성
  • 단계별로 내부 동작 
 
const p1 = new Person("Alice", 25);
  1. 새로운 빈 객체 생성 → {}
  2. 생성자 함수(Person) 호출, this가 새 객체를 가리킴
  3. 생성자 내부 코드 실행 (this.name = name, this.age = age)
  4. 새 객체(인스턴스) 반환 p1에 저장

즉, new는 단순히 객체를 만드는 연산자가 아니라
**“클래스/생성자 함수 기반으로 새 객체(인스턴스)를 생성”**하는 역할을 합니다.


🔹 요약

용어 의미
객체 데이터를 담은 상자 { key: value }
인스턴스 클래스/생성자 함수를 기반으로 만들어진 객체
클래스 객체 설계도, ES6 문법
생성자 함수 클래스 이전 방식, 객체 설계도 함수
new 클래스/생성자 함수 새 인스턴스 생성

💡 핵심:

  • 객체 = 그냥 상자, 인스턴스 = 설계도 기반으로 만든 상자
  • new는 객체를 만들기 위한 도구지만, 클래스/생성자 함수와 함께 쓰여 인스턴스를 생성

 

728x90
반응형