Axios 사용법

이보아·2024년 6월 11일

Axios란?

자바스크립트에서 HTTP 요청을 쉽게 만들 수 있게 해주는 라이브러리입니다. 이를 사용하면 서버와 데이터를 주고받는 게 훨씬 간편합니다.


Axios 설치하기

npm install axios

Axios로 데이터 다루기

Axios로 데이터 가져오기 (GET 요청)

import axios from 'axios';

axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data); // 서버에서 받은 데이터를 출력합니다.
  })
  .catch(error => {
    console.error('데이터 가져오기 오류:', error);
  });

  • 어떤 웹사이트에서 데이터를 가져오고 싶다면 axios를 위 예제처럼 사용하여 가져올 수 있습니다.

번외 / Fetch API로 데이터 가져오기 (GET 요청)

// Fetch API는 자바스크립트에 내장된 함수이다. 
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    console.log(data); // 서버에서 받은 데이터를 출력합니다.
  })
  .catch(error => {
    console.error('데이터 가져오기 오류:', error);
  });

Axios로 데이터 보내기 (POST 요청)

import axios from 'axios';

const data = {
  name: '홍길동',
  age: 25
};

axios.post('https://api.example.com/users', data)
  .then(response => {
    console.log('서버 응답:', response.data);
  })
  .catch(error => {
    console.error('데이터 보내기 오류:', error);
  });
  • axios를 위 예제처럼 사용하여 서버에 데이터를 보낼 수 있습니다.

번외 / Fetch API로 데이터 보내기 (POST 요청)

const data = {
  name: '홍길동',
  age: 25
};

fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(data => {
    console.log('서버 응답:', data);
  })
  .catch(error => {
    console.error('데이터 보내기 오류:', error);
  });

실제로 Axios를 사용하는 것이 코드가 조금 더 간결해 보였다. 그래서 Fetch API와 Axios의 차이점과 장단점을 알아보고 싶어서 조금 더 찾아보았다. 🤔


Axios와 Fetch API 비교

특징Fetch APIAxios
간단한 구문.then(response => response.json())와 같은 추가 작업 필요자동으로 JSON 파싱, 더 간단한 구문 사용 가능
에러처리네트워크 오류만 catch 블록에서 처리, HTTP 상태 코드 오류 추가 확인 필요HTTP 상태 코드 오류도 catch 블록에서 처리 가능
Interceptors제공되지 않음요청과 응답에 인터셉터 추가 가능, 요청 전에 인증 토큰 추가 및 응답 전에 에러 처리 가능
브라우저 호환성최신 브라우저에서만 기본적으로 지원구형 브라우저에서도 잘 작동

Axios를 사용하면 더 간단하고 직관적으로 HTTP 요청을 처리할 수 있다.


Axios Interceptor 적용하기

Interceptor란?

Interceptor는 HTTP 요청과 응답을 가로채서 특정 작업을 수행할 수 있게 합니다. 예를 들어, 응답에 대한 공통적인 에러 처리를 할 수 있습니다.

  • 요청(request): 전송되기 전(또는 요청을 보내기 전, 또는 요청이 출발하기 전)
  • 응답(response): then(성공) 또는 catch(실패)가 처리되기 전

Interceptor 예시

Interceptor를 사용하면 요청 및 응답 시 필요한 작업을 한꺼번에 처리할 수 있습니다.

  • 요청 헤더 추가
  • 인증 관리
  • 로그 관련 로직 삽입
  • 에러 핸들링

Interceptor 예제

src / axios / api.js

import axios from "axios";

// 공통으로 사용하는 URL 
const instance = axios.create({
  baseURL: "http://localhost:4000",
});

instance.interceptors.request.use(
  function (config) {
    // 요청을 보내기 전 수행
    console.log("인터셉트 요청 성공!");
    return config;
  },
  function (error) {
    // 오류 요청을 보내기 전 수행
    console.log("인터셉트 요청 오류!");
    return Promise.reject(error);
  }
);

instance.interceptors.response.use(
  function (response) {
    console.log("인터셉트 응답 받았어요!");
    // 정상 응답
    return response;
  },
  function (error) {
    console.log("인터셉트 응답 못받았어요...ㅠㅠ");
    return Promise.reject(error);
  }
);

export default instance;


요청 실패 한다면?

import axios from "axios";

const instance = axios.create({
  baseURL: "http://localhost:4000",
  timeout: 1, // 1ms <- 일부로 엄청 짧은시간으로 설정하여, 실패하게 함
});

export default instance;

  • 타임아웃이 초과되어 응답을 받지못한 로그를 출력한다.

더 활용할 수 있는 부분

  • 요청 시, content-type 적용
  • 토큰 등 인증 관련 로직 적용
  • 서버 응답 코드에 대한 오류 처리
  • 통신 시작 및 종료에 대한 전역 상태 관리로 스피너, 프로그레스 바 구현


Axios 사용하여 회원가입 기능 구현하기

사용자가 닉네임, 아이디, 비밀번호를 입력하고, '회원가입' 버튼을 클릭하면 서버에 데이터를 보내서 회원가입을 완료하는 기능을 구현했습니다. 그 과정에서 axios, Interceptor 를 적용하여 만들었습니다.


import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import api from '../axios/api'; // 생성한 Interceptor 불러옴
import styled from 'styled-components';

const SignUpForm = styled.div`
    width: 100%;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    h1 {
        width: 150px;
        margin-bottom: 20px;

        img {
            width: 100%;
        }
    }

    form {
        width: 300px;

        input {
            display: block;
            width: 100%;
            padding: 8px 10px;
            margin-bottom: 10px;
            border: 1px solid rgb(208, 208, 208);
            outline: none;
            box-sizing: border-box;
        }

        label {
            position: absolute;
            width: 1px;
            height: 1px;
            padding: 0;
            overflow: hidden;
            clip: rect(0, 0, 0, 0);
            white-space: nowrap;
            border: 0;
        }
        button {
            width: 100%;
            padding: 8px;
            background-color: var(--main-color);
            color: #fff;
            font-weight: 600;
            border-radius: 0;

            &:hover {
                background-color: var(--main-hover-color);
            }
        }
    }
`;

const Signup = () => {
    const [nickname, setNickname] = useState('');
    const [id, setId] = useState('');
    const [password, setPassword] = useState('');
    const [confirmPassword, setConfirmPassword] = useState('');
    const navigate = useNavigate();

    const handleSignUp = async (e) => {
        e.preventDefault();
        if (password !== confirmPassword) {
            alert('비밀번호가 일치하지 않습니다. 다시 확인해주세요.');
            return;
        }

        try {
          // Interceptor 적용했기때문에 baseURL 뒤에 부분만 작성하면 됨 
            const response = await api.post('/register', {
                id,
                password,
                nickname,
            });
            const data = response.data;
            if (data.success) {
                navigate('/login');
            } else {
                alert('회원가입 실패하였습니다.');
            }
        } catch (error) {
            console.error('Signup error:', error);
            alert('회원가입 실패하였습니다.');
        }
    };

    return (
        <SignUpForm>
            <h1>
                <img src="/logo.png" alt="로고" />
            </h1>
            <form onSubmit={handleSignUp}>
                <label>닉네임</label>
                <input
                    type="text"
                    value={nickname}
                    onChange={(e) => setNickname(e.target.value)}
                    placeholder="닉네임"
                />
                <label>아이디</label>
                <input type="text" value={id} onChange={(e) => setId(e.target.value)} placeholder="ID" />
                <label>비밀번호</label>
                <input
                    type="password"
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                    placeholder="비밀번호"
                />
                <label>비밀번호 확인</label>
                <input
                    type="password"
                    value={confirmPassword}
                    onChange={(e) => setConfirmPassword(e.target.value)}
                    placeholder="비밀번호 확인"
                />
                <button>회원가입</button>
            </form>
        </SignUpForm>
    );
};

export default Signup;


참고사이트 🙇‍♀️

How to Implement a Request Interceptor Like Axios

profile
매일매일 틀깨기

0개의 댓글