카테고리 없음

[엘리스트랙 11주차] Fetch와 Axios

불곰자리 2023. 11. 23. 23:57

오늘 실습에서 Axios API를 사용해 데이터를 요청했다. (왜 썼는지 이유는 기억나지 않지만...)
예전부터 Fetch와 Axios의 차이가 궁금했었는데 오늘 배운 김에 정리해보고자한다.

 

우선 공식 문서를 참조하여 각 API의 정의와 함께 차이점을 정리하려한다. 

Axios

Axios는, Node.js와 브라우저를 위한 Promise 기반의 HTTP 클라이언트다. 이것은 동형(Isomorphic)이(=같은 코드를 기반으로 브라우저와 Node.js 둘 다 실행이 가능하다.)라고 불린다. 서버 쪽에서는 네이티브의 Node.js http 모듈을 사용하고, 클라이언트(브라우저)에서는 XMLHttpRequests를 사용한다. 

 

특징

  • 브라우저로부터 XMLHttpRequests를 생성
    XMLHttpRequests는 서버로부터 XML 데이터를 전송 받아 처리하는 객체이다.
  • Node.js로부터 http 요청을 생성
  • Promise API를 지원
  • 인터셉트 요청과 응답이 가능
  • 요청과 응답 데이터의 변환
  • 요청을 취소
  • JSON 데이터로의 자동 변환
  • XSRF로부터 보호하기 위한 클라리언트 측 지원
    XSFR(CSFR)은 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 하는 공격으로, 사용자가 로그인 상태일 때 공격자에 의해 삽입된 악성 경로(웹 사이트 DB에 접근해 데이터를 조작하는 등을 수행)에 접근하면 의도하지 않은 데이터의 요청이 일어나지만, 웹사이트에선 사용자의 쿠키나 세션 값만을 확인하기 때문에 정상적인 접근이라 생각하고 요청을 처리한다.

예시

const axios = require('axios');

// 지정된 ID의 유저에 대한 요청을 처리
axios.get('/user?ID=12345')
  .then(function (response) {
    // 요청이 성공한 경우
    console.log(response);
  })
  .catch(function (error) {
    // 에러 처리
    console.log(error);
  })
  .then(function () {
    // 무조건 실행
  });

 

응답 환경 설정

{
  // `url` 은 요청에 사용되는 서버의 URL이다.
  url: '/user',

  // `method` 는 요청을 실행하는 쪽에서 사용되는 요청 메서드이다.
  method: 'get', // default

  // `url` 이 절대경로가 아닌 경우、`baseURL` 이 `url` 의 앞에 붙는다.
  // Axios 의 인스턴스에 `baseURL` 을 설정하면、그 인스턴스의 메서드에 절대 경로로
  // URL을 건네줄 수 있어、편리하다.
  baseURL: 'https://some-domain.com/api',

  // `transformRequest` 는、서버에 송신되기 전 요청 데이터를 변경할 수 있도록 한다.
  // 이 요청 메서드는 'PUT'、'POST'、PATCH'、'DELETE' 에 대해서만 적용된다.
  // 배열의 마지막에 함수는、문자열이나 Buffer、ArrayBuffer、FormData、Stream 인스턴스를 반환할필요가 있다.
  // 헤더 객체를 변경할 수 있다.
  transformRequest: [function (data, headers) {
    // 데이터의 변환 처리를 실행

    return data;
  }],

  // `transformResponse` 을 사용하면、응답 데이터를 변경하여 then/catch 에 넘겨줄 수 있다.
  transformResponse: [function (data) {
    // 데이터의 변환 처리를 실행

    return data;
  }],

  // `headers` 는 전송되는 커스텀 헤더이다.
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // `params` 는、요청과 함께 전송되는 URL 파라미터다.
  // 플레인 객체 또는 URLSearchParams 객체일 필요가 있다.
  // 주의: null 이나 정의되지 않은 파라미터는 URL에 렌더링되지 않는다.
  params: {
    ID: 12345
  },

  // `paramsSerializer` 는、 `params` 의 직렬화를 담당하는 옵션 함수이다.
  // (예를 들어、https://www.npmjs.com/package/qs、http://api.jquery.com/jquery.param/)
  paramsSerializer: function (params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  },

  // `data` 는 요청 바디의 형태로 전송되는 데이터다.
  // 요청 메서드 'PUT'、'POST'、'DELETE'、'PATCH' 에 대해서만 적용 가능하다.
  // `transformRequest` 가 설정되지 않은 경우、아래의 형태여야 한다.
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 브라우저의 경우: FormData, File, Blob
  // - Node.js의 경우: Stream, Buffer
  data: {
    firstName: 'Fred'
  },
  
  // 바디에 데이터를 송신하기 위한 대체 구문
  // POST 메서드
  // key가 아닌、value만 전송된다.
  data: 'Country=Brasil&City=Belo Horizonte',

  // `timeout`는、요청이 타임아웃되기 까지의 밀리초를 설정한다.
  // 요청에 `timeout`보다 긴 시간이 걸리는 경우、요청이 중지된다.
  timeout: 1000, // 기본값은 `0` (타임아웃 없음)

  // `withCredentials` 는、자격 정보를 사용해 CORS의
  // 요청을 실행할지 말지 결정한다.
  withCredentials: false, // 기본값

  // `adapter`을 사용하면、요청에 대한 처리를 사용자가 설정할 수 있어、테스트가 간단해진다.
  // Promise를 반환하고、유효한 응답을 제공한다. (lib/adapters/README.md 를 참조)
  adapter: function (config) {
    /* ... */
  },

  // `auth` 는、HTTP 기본 인증을 사용할 필요가 있음을 표시하며、자격 정보를 제공한다.
  // 이에 따라、 `Authorization` 헤더가 설정되며、`headers`를 사용해 설정한
  // 기존 `Authorization` 커스텀 헤더를 덮어쓴다.
  // 이 파라미터를 사용해 구성할 수 있는 건、HTTP 기본인증만 할 수 있다는 것에 주의해야한다.
  // Bearer 토큰의 경우、대신 `Authorization` 커스텀 헤더를 사용해야 한다.
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // `responseType` 는、아래와 같은 서버옵션으로 응답하는 데이터 타입을 설정한다.
  // 'arraybuffer'、'document'、'json'、'text'、'stream'
  //   브라우저의 경우: 'blob'
  responseType: 'json', // 기본값

  // `responseEncoding` 은、응답을 디코딩하는 데 사용하는 엔코드 방법을 설정한다. (Node.js의 경우)
  // 주의: `responseType` 가 'stream' 일 경우、또는 클라이언트 측의 요청은 무시된다.
  responseEncoding: 'utf8', // 기본값

  // `xsrfCookieName` 는、xsrf 토큰의 값으로 사용될 Cookie의 이름이다.
  xsrfCookieName: 'XSRF-TOKEN', // 기본값

  // `xsrfHeaderName` 는、xsrf 토큰 값이 들어갈 http 헤더의 이름이다. 
  xsrfHeaderName: 'X-XSRF-TOKEN', // デフォルト

  // `onUploadProgress` 을 사용하면、업로드 진행 상황 이벤트의 처리가 가능하다.
  // 브라우저의 경우
  onUploadProgress: function (progressEvent) {
    // 네이티브의 진행 상황 이벤트를 처리한다.
  },

  // `onDownloadProgress` 을 사용하면、다운로드 진행 상황 이벤트 처리가 가능하다.
  // 브라우저의 경우
  onDownloadProgress: function (progressEvent) {
    // 네이티브의 진행 상황 이벤트를 처리한다.
  },

  // `maxContentLength` 는 Node.js에 가능한 http 응답 컨텐츠의 최대 크기를 바이트 수로 정의한다.
  maxContentLength: 2000,

  // `maxBodyLength` (Node.js 쪽의 옵션)은、http 요청 컨텐츠의 최대 사이즈를 바이트 수로 정의한다.
  maxBodyLength: 2000,

  // `validateStatus` 는、주어진 HTTP 응답의 상태 코드에 대해서、Promise 를 받아올지 거부할지 정의한다.
  // `validateStatus` 가 `true`를 반환할 때 (또는 `null` 이나 `undefined`로 설정되어있는 경우) Promise를 받아온다. 
  // 그 외의 경우 Promise는 거부된다.
  validateStatus: function (status) {
    return status >= 200 && status < 300; // 기본값
  },

  // `maxRedirects`는 Node.js에서 리다이렉트를 추적하는 최대 수를 정의한다.
  // 0으로 설정하면、리다이렉트를 실행하지 않는다.
  maxRedirects: 5, // 기본값

  // `socketPath`는、Node.js에서 사용하는 UNIX 소켓을 정의한다.
  // 예를 들어 '/var/run/docker.sock'를 사용해、Docker 데몬에 요청을 전송한다.
  // 지정 가능한 것은 `socketPath` 또는 `proxy` 중 하나다.
  // 둘 다 설정하면、`socketPath`가 사용된다.
  socketPath: null, // 기본값

  // `httpAgent` 와 `httpsAgent` 는、각자 Node.js에서 http와 https의 요청을
  // 실행할 때 사용하는 커스텀 에이전트를 정의한다.
  // 그에 따라、기본값으로는 유효 값으로 설정되지 않은 `keepAlive`와 같은 옵션 추가가 가능하다.
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // `proxy`는、프록시 서버의 호스트 명、포트、프로토콜 정의가 가능하다.
  // 또、기존의 `http_proxy` 와 `https_proxy` 환경 변수를 사용해、프록시 정의가 가능하다.
  // 프록시 설정에 환경 변수를 사용할 경우、프록시를 설정하지 않은 도메인의 콤마(,)로 구분되는 리스트로서
  // `no_proxy` 환경 변수를 정의할 수도 있다.
  // 환경 변수를 무시하고 프록시를 무효로 처리하고자 한다면、 `false`를 사용한다.
  // `auth`는、프록시의 접속에 HTTP 기본 인증을 사용하는 것을 표시하고、인증 정보를 제공한다.
  // 그에 따라、`Proxy-Authorization`헤더가 설정되어、`headers`를 사용해 설정했던 기존의
  // `Proxy-Authorization` 커스텀 헤더가 덮어 씌워진다.
  // 프록시 서버가 HTTPS를 사용하는 경우、프로토콜을 `https`로 설정할 필요가 있다. 
  proxy: {
    protocol: 'https',
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // `cancelToken`에는、요청을 취소하기 위해 사용하는 취소 토큰을 설정한다.
  cancelToken: new CancelToken(function (cancel) {
  }),

  // `decompress` 는、응답 바디를 자동으로 압축 해제할지를 지정한다.
  // `true`로 설정할 경우、모든 압축 해제된 응답의 응답 객체로부터
  // 'content-encoding' 헤더도 삭제된다.
  // - Node의 경우 (XHR false로 설정이 불가능하다.)
  decompress: true // 기본값

}

 

Fetch

Fetch API는 Request와 Response 객체(및 네트워크 요청에 관련된 다른 것들)의 범용적인 정의가 제공된다. 이를 통해, 서비스 워커, 캐쉬 API, Request나 Response를 처리하거나 변환하는 등의 유사한 것, 또는 프로그램 적으로 Response를 생성할(즉, 컴퓨터 프로그램 또는 개인의 프로그래밍 명령을 사용함) 필요가 있는 모든 종류의 사용법이나, 이후에 필요로 여겨지는 모든 경우에 사용할 수 있다. 

또, CORS나 HTTP의 Origin 헤더의 메서드에 관련된 개념에 대해 정의되어있다. 이 정의는, 현재 분산되어있는 각 정의를 대체하는 것이다. 

리소스 획득을 위한 Request는 fetch() 메서드를 호출하여 작성될 수 있다. 이 메서드는 Window나 WorkerGloblaScope라는 인터페이스에 의해 새로 추가되었다. 그 결과, 리소스 획득을 필요로하는 여러 경우에 이용이 가능하다.

fetch() 메서드는 무조건 하나의 인자를 가지며, 획득하고자하는 리소스의 경로를 지정한다. Promise를 반환한다. 서버가 헤더로 응답하면 바로, 서버 응답이 HTTP 에러 상태라고 해도, Response로 반환된다. 두 번째 인자는 init 옵션 객체를 건네줄 수 있다.

Response를 받으면, Response에 포함된 콘텐츠와, Response의 처리 방법을 정의하기 위한 다수의 메서드를 이용할 수 있다.

Request() 및 Response()를 이용하는 것으로, Request와 Response를 직접 작성할 수 있다. 그러나 이 옵션은,
FetchEvent.respondWith()와 같은 다른 API를 호출하는 결과로서 획득할 수 있으므로, 직접 작성하지 않는 경우가 좋다.

 

Request 속성

Request.body 읽기 가능한 바디 컨텐츠
Request.bodyUsed 바디가 요청에 쓰였는지 아닌지 여부(true, false)를 저장
Request.cache 요청의 캐시 모드를 포함(default, reload, no-cache)
Request.credentials 요청의 credentials를 포함(omit, same-origin, include)
Request.destination 요청되는 데이터의 컨텐츠 타입을 문자열로 설명
Request.headers 요청과 관련된 Headers객체를 포함
Request.integrity 요청에 하위 리소스의 무결성 값을 포함
Request.method 요청의 메소드를 포함(GET, POST 등)
Request.mode 요청의 모드를 포함(cors, no-cors, same-origin, navigate)
Request.redirect 리다이렉트의  처리 방법을 포함(follow, error, manual)
Request.referrer 요청의 referrer를 포함 (client)
Request.referrerPolicy 요청의 referrer 정책을 포함 (no-referrer)
Request.signal 요청과 관련한 AbortSignal을 반환
Request.url 요청의 URL을 포함

 

Axios와 Fetch의 차이점

Axios Fetch
request 객체에 url를 갖는다. request 객체에 url이 없다.
설치가 쉬운 독립적인 서드파티 패키지이다. 현대 브라우저에 기본적으로 내장되어 있다.
XSRF 보호 기능이 내장되어 있다. XSRF 보호 기능이 없다.
data property를 사용해 데이터를 전송한다. body property를 사용해 데이터를 전송한다.
data는 객체를 가진다. body는 문자열로 변형되어 보내진다.
JSON 데이터로 자동 변환이 가능하다. json() 메서드를 이용해 JSON 데이터를 받아와야 한다.
응답 취소 및 타임아웃 설정이 가능하다. 응답 취소 및 타임아웃 설정이 불가능하다.
HTTP 요청을 인터셉트할 수 있다. 요청을 인터셉트하는 방법이 제공되어있지 않다.
GET 요청 시 data property를 무시한다. GET 요청 시 body에 데이터 첨부가 가능하다.
  상태 코드가 404또는 500일 때도
Promise 반환이 거부되지 않고, ok값이 false로 변한다.
  credentials의 초기화 옵션을(include로) 설정하지 않는다면,
오리진을 포함한 Cookie를 전송하지 않는다.
  예전 브라우저 버전을 사용하는 경우,
Cookie/유저 로그인 상태의 영향을 받을 수 있는
가능성이 있는 모든 API 요청에 'same-origin'을
초기화 옵션으로 설정한 인증 정보를 포함해야 한다.

 

#엘리스트랙 #엘리스트랙후기 #리액트네이티브강좌 #온라인코딩부트캠프 #온라인코딩학원 #프론트엔드학원 #개발자국비지원 #개발자부트캠프 #국비지원부트캠프 #프론트엔드국비지원 #React #Styledcomponent #React Router Dom #Redux #Typescript #Javascript