Santos의 개발블로그

axios 본문

NPM/Valuable

axios

Santos 2020. 7. 26. 23:05

* 이 글은 https://www.npmjs.com/package/axios 번역하였습니다. 

 

Promise를 기반으로 브라우져, node.js 를 위한 HTTP client 입니다.

#1: Features

- 브라우저로부터 XMLHttpRequests를 만듭니다.

- node.js 로부터 http 요청을 만듭니다. 

- Promise API를 기반으로 합니다. 

- 요청과 응답을 Intercept 합니다.

- 요청과 응답 데이터를 변형시킵니다. 

- 요청을 취소합니다. 

- 자동으로 JSON 데이터로 변형시킵니다.

- XSRF를 Client side에서 보호합니다.

#2: Browser Support

#3: Install

npm 

$ npm install axios

bower

$ bower install axios

yarn

$ yarn add axios

cdn

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

#4: Example

@4-1 GET 요청 실행

const axios = require('axios');
 
// user에게 할당된 id 값과 함께 요청을 합니다.
axios.get('/user?ID=12345')
  .then(function (response) {
    // 성공했을 때
    console.log(response);
  })
  .catch(function (error) {
    // 에러가 났을 때
    console.log(error);
  })
  .finally(function () {
    // 항상 실행되는 함수
  });
 
// 위와는 같지만, 옵션을 주고자 할 때는 이렇게 요청을 합니다.
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .finally(function () {
    // always executed
  });  
 
// async/await 를 쓰고 싶다면 async 함수/메소드를 만듭니다. 
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}
Note: ECMAScript 2017의 한 부분인 async/await는 IE, 오래된 브라우저는 지원하지 않습니다.

@4-2 POST 요청 실행

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

@4-3 2개이상 동시에 요청 실행

function getUserAccount() {
  return axios.get('/user/12345');
}
 
function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}
 
axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 두개의 요청이 성공했을 때
  }));

#5: axios API

요청은 axios에게 관련된 설정을 보냄으로써 만들어집니다.

// POST 요청을 보낼 때
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
// 원격 이미지 GET 요청을 보낼 때
axios({
  method: 'get',
  url: 'http://bit.ly/2mTM3nY',
  responseType: 'stream'
})
  .then(function (response) {
    response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
  });

@5-1 요청 메소드 aliases

- 편리하게 사용하기 위해 모든 요청 메소드는 aliases가 제공됩니다.

axios.request(config)

axios.get(url[, config])

axios.delete(url[, config])

axios.head(url[, config])

axios.options(url[, config])

axios.post(url[, data[, config]])

axios.put(url[, data[, config]])

axios.patch(url[, data[, config]])

// url, method, data를 사용할 때, 속성들을 config에 일일이 지정할 필요가 없습니다.  

@5-2 동시성

- 동시 요청을 위한 유용한 함수입니다.

axios.all(iterable)

axios.spread(callback)

@5-3 Instance 만들기

- custom 속성을 지닌 axios의 new instance를 만들 수 있습니다.

axios.create([config])

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

@5-4 Instance 메소드

- Instance 메소드는 다음과 같습니다. 본래 지정된 설정들은 instance 설정과 합쳐집니다.

axios#request(config)

axios#get(url[, config])

axios#delete(url[, config])

axios#head(url[, config])

axios#options(url[, config])

axios#post(url[, data[, config]])

axios#put(url[, data[, config]])

axios#patch(url[, data[, config]])

axios#getUri([config])

#6:Request Config

요청을 만드는 유효한 설정 옵션들입니다. 요청할 때 url은 필수이며, 요청 메소드를 명시하지 않았을 때 default는 GET입니다. 

url 

 - url 은 server url 이며 요청하기 위해 사용됩니다.

url: '/user',
method

- method는 요청을 할 때 사용되어지는 요청 방식입니다.

method: 'get', // default
baseURL

- baseURL운 url이 절대적이지 않을 경우 url 맨 앞에 붙는 주소입니다.
- 상대적인 URL을 axios instance가 instance의 메소드에게 전달하기 위해서 편리하게 baseURL을 셋팅을 할 수 있습니다. 

baseURL: 'https://some-domain.com/api/'
transformRequest

- transformRequest는 server에 전달되기 전에 요청 데이터를 바꿀 수 있습니다.
- 요청 방식 'PUT', 'POST', 'PATCH', 'DELETE' 에 해당하는 경우에 이용가능합니다.
- 배열의 마지막 함수는 string 또는 Buffer, 또는 ArrayBuffer를 반환합니다.
- header 객체를 수정할 수 있습니다.

transformRequest: [function (data, headers) { 
    // Do whatever you want to transform the data 
  
    return data; 
  }],
transformResponse   

- transformResponse는 응답 데이터가 만들어지기 전에 변환할 수 있습니다.

- then/catch로 전달됩니다.

  transformResponse: [function (data) {
    // Do whatever you want to transform the data
 
    return data;
  }],
headers

- headers을 이용해 사용자 정의 header를 보낼 수 있습니다.

 headers: {'X-Requested-With': 'XMLHttpRequest'}
params

- params를 이용해 요청과 함께 URL 파라미터로 보낼 수 있습니다.

- 객체 또는 URLSearchParams object여야 합니다.

 params: {
    ID: 12345
  },
paramsSerializer

- paramsSerializer는 params를 직렬화하는 선택적인 함수입니다.

  paramsSerializer: function (params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  },

 

data

-  data는 요청할 때 body에 포함시켜 보낼 수 있습니다.

- 요청 방식이 'PUT', 'POST', 'PATCH' 해당하는 경우 가능합니다.

- transformRequest를 셋팅하지 않았을 때, 아래 타입 중 하나로 보내야 합니다.

  • 공통: string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  • only 브라우저: FormData, File, Blob
  • only Node: Stream, Buffer
 data: {
    firstName: 'Fred'
  },

- body에 포함시켜 보내지 않는 문법입니다.

- 요청방식이 'POST'에만 해당됩니다. 

- 요청으로 선언한 값만 보내집니다. (키는 X)

 data: 'Country=Brasil&City=Belo Horizonte'
timeout

- timeout은 요청 timeout이 발동 되기 전 milliseconds의 시간을 요청 timeout으로 지정합니다.

- timeout 보다 요청이 길어진다면, 요청은 취소됩니다.

 timeout: 1000, // default is `0` (no timeout)
withCredentials

- withCredentials은 cross-site access-control 요청을 허용 유무를 가리킵니다. 

withCredentials: false, // default
adapter

- adapter는 테스트를 쉽게하도록 하는 사용자 정의 요청을 허용하도록 합니다. 

- 유효한 응답값을 제공하고, promise를 반환합니다.

 adapter: function (config) {
    /* ... */
  },
auth

- auth는 HTTP의 기본 인증을 사용하는 것을 가리키고, 신임장을 제공합니다.

- auth는 권한 부여를 헤더에 셋팅하고, headers를 사용하여 사용자 헤더에 셋팅을 하게 되면 기존 인증을 덮어씁니다.

- auth를 통해서 HTTP의 기본 인증이 구성이 가능하다는 것을 알아두세요.

- Bearer 토큰 등을 위한 것입니다. 

 auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },
responseType

- responseType은 서버가 응답해주는 데이터의 타입(arraybuffer, documetn, json, text, stream, blob)을 나타냅니다.

  responseType: 'json', // default
responseEncoding

- responseEncoding은 디코딩 응답에 사용하기 위한 인코딩을나타냅니다.

- stream 그리고 client-side 요청의 responseType은 무시됩니다.

 responseEncoding: 'utf8', // default
xsrfCookieName

- xsrfCookieName은 xsrf 토큰을 위한 값으로써 사용할 수 있는 쿠키입니다.

xsrfCookieName: 'XSRF-TOKEN', // default
xsrfHeaderName

- xsrfHeaderName은 xsrf 토큰의 값을 운반하는 http 헤더입니다.

xsrfHeaderName: 'X-XSRF-TOKEN', // default
onUploadProgress

- onUploadProgress는 다루는 것을 업로드를 위한 progress event를 허용하도록 하는 옵션입니다.

 onUploadProgress: function (progressEvent) {
    // Do whatever you want with the native progress event
  },
onDownloadProgress

- onDownloadProgress는 다운로드를 위한 progress event를 허용하도록 하는 옵션입니다.

onDownloadProgress: function (progressEvent) {
    // Do whatever you want with the native progress event
  },
maxContentLength

- maxContentLength는 http 응답 내용의 max 사이즈를 지정하도록 하는 옵션입니다.

maxContentLength: 2000,
validateStatus

- validateStatus는 주어진 HTTP응답 상태 코드에 대해 promise의 반환 값이 resolve 또는 reject 할지 지정하도록 하는 옵션입니다.

- 만약 validateStatus의 반환 값을 true 로 한다면 promise는 resolve가 된다. 만약 false라면 promise는 reject를 반환합니다.

validateStatus: function (status) {
    return status >= 200 && status < 300; // default
  },
maxRedirects

- maxRedirects는 node.js에서 사용되는 리다이렉트 최대치를 지정합니다.

- 만약 0으로 셋팅을 했다면, 리다이렉트가 발생하지 않습니다.

 maxRedirects: 5, // default
socketPath

- socketPath는 node.js에서 사용되는 UNIX 소켓을 지정합니다.

예시: '/var/run/docker.sock' 지정하면 docker daemon으로 요청을 보낸다. 

- socketPath 나 proxy 에서만 지정할 수 있습니다. 만약 둘다 지정한다면 socketPath로 사용됩니다.

socketPath: null, // default
httpAgent, httpsAgent

- httpAgent, httpsAgent는 node.js에서 http나 https를 요청을 할때 사용자 정의 agent를 정의하는 옵션입니다.

- `keepAlive`와도 같은 추가되는 옵션을 허용합니다. default는 따로 지정되어 있지 않습니다.

  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),
proxy

- proxys는 proxy서버의 hostname과 port를 정의하는 옵션입니다.

- 또한 전통적으로 사용하는 환경변수 http_proxy`나 https_proxy`를  proxy configuration으로 정의할 수 있고, no_proxy 또한 프록시 되지 않은 도메인에 쉼표 구분을 통해서 환경변수로 정의할 수 있습니다.

- false를 사용하면 proxies 가 disable 되면서 환경변수를 무시합니다. 

- HTTP Basice auth를 나타내는 'auth'는 poxxy에 연결하는데 사용되어 지고, 신임장을 제공합니다.

- poxys는 존재하는 Proxy-Authorization의 커스텀 헤더를 덮어씌우면서 Proxy-Authorization의 헤더를 셋팅합니다. 

  proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },
cancelToken

- cancelToken은 요청을 취소하는데 사용되어 지는 취소토큰을 명시합니다. 

  cancelToken: new CancelToken(function (cancel) {
  })

#7:Response Schema

요청을 통해 받는 응답의 정보는 다음과 같습니다. 

data

- Data는 sever에서 제공되는 응답 값입니다. 

data: {},
status

- Status는 서버 응답에 대한 HTTP 상태 코드 입니다.

status: 200,
StatusText

- StatusText는 서버 응답에 대한 HTTP상태 메시지 입니다.

statusText: 'OK',
headers

- headers는 서버 응답에 대한 헤더이고, 헤더의 이름들은 소문자로 들어옵니다.

headers: {},
config

- config는 axiom 요청에 대해 제공되는 config입니다.  

config: {},
request

- request는 응답을 만든 요청입니다. Node.js 에서 마지막 ClientRequest, 브라우저에서는 XMLHttpRequest의 instance 값 입니다.

- then 키워드를 사용해 아래의 예시처럼 응답 값을 받을 수 있습니다. 

request: {}

- then 두번째 파라미터인 catch 키워드를 사용해 rejection callback 전달할  있습니다들어오는 응답은 Handling Errors 섹션에 설명되어 있는 error 객체를 통해 사용할  있습니다.

#8:Config Defaults

- 모든 요청에 적용되는 설정의 default 값을 명시할 수 있습니다.

 

@8-1 Global axis defaults 

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

@8-2Custom instance defaults

// Instance를 만들 때 설정의 default 값을 설정할 수 있습니다.
const instance = axios.create({
  baseURL: 'https://api.example.com'
});
 
// Instance를 만든 후  defalut 값을 수정할 수 있습니다. 
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

@8-3Config order of precedence

- 설정들은 우선순위에 따라서 합쳐집니다. 

- 순서는 (lib/defaults.js)에서 확인 가능한 library defaults, instance의 default 속성, 마지막으로 요청을 위한 config 인자들입니다. 

- 후자가 전자보다 더 우선합니다. 

- 아래는 예시입니다. 

// Create an instance using the config defaults provided by the library
// At this point the timeout config value is `0` as is the default for the library
const instance = axios.create();
 
// Override timeout default for the library
// Now all requests using this instance will wait 2.5 seconds before timing out
instance.defaults.timeout = 2500;
 
// Override timeout for this request as it's known to take a long time
instance.get('/longRequest', {
  timeout: 5000
});

#9:Interceptors

- then 또는 catch로 처리되기 전 요청 또는 응답 값을 가로챌 수 있습니다.  

// 요청 interceptors를 추가하는 함수입니다.
axios.interceptors.request.use(function (config) {

    // Do something before request is sent
    
    return config;
    
  }, function (error) {
  
    // Do something with request error
    
    return Promise.reject(error);
  });
 
 
 
// 응답 interceptors를 추가하는 함수입니다.
axios.interceptors.response.use(function (response) {

    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    
    return response;
    
  }, function (error) {
  
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    
    return Promise.reject(error);
  });

- 만약 interceptors를 제거하고 싶다면 아래 코드를 살펴보세요 

const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

- Custom instance에서 interceptors를 추가할 수 있습니다. 

const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

#10:Handling Errors

axios.get('/user/12345')
  .catch(function (error) {
  
    if (error.response) {
    
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
      
    } else if (error.request) {
    
      // The request was made but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      
      console.log(error.request);
      
    } else {
    
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
      
    }
    
    console.log(error.config);
    
  });

- validateStatus을 설정 옵션으로 사용하는 것은 error를 던지는 HTTP 코드들을 정의할 수 있습니다..  

axios.get('/user/12345', {
  validateStatus: function (status) {
  return status < 500; // Reject only if the status code is greater than or equal to 500
  }
})

- toJson을 사용하는 것은 HTTP error에 관한 보다 많은 정보가 담긴 객체를 얻을 수 있습니다. 

axios.get('/user/12345')
  .catch(function (error) {
    console.log(error.toJSON());
  });

#10:Cancellation

- 취소 토큰을 사용하여 요청을 중단할 수 있습니다. 

- 밑에 보이는 코드처럼 CancelToken.source를 이용하여 취소 토큰을 만들수 있습니다.

const CancelToken = axios.CancelToken;
const source = CancelToken.source();
 
axios.get('/user/12345', {

  cancelToken: source.token
  
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
  
    console.log('Request canceled', thrown.message);
    
  } else {
    // handle error
  }
});
 
axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})
 
// cancel the request (the message parameter is optional)

source.cancel('Operation canceled by the user.');

- excutor function를 CancelToken 생성자에 전달하여 취소 토큰을 만들수도 있습니다.

const CancelToken = axios.CancelToken;
let cancel;
 
axios.get('/user/12345', {

  cancelToken: new CancelToken(function executor(c) {
  
    // An executor function receives a cancel function as a parameter
    cancel = c;
  
  })
});
 
// cancel the request
cancel();

#11:Using application/x-www-form-urlencoded format

- 기본적으로 Axisos 는 객체를 JSON으로 직렬화 시킵니다. 대신 application/x-www-form-urlencoded 형식으로 데이터를 보내려면 아래의 옵션을 사용해야 합니다. 

 

@11-1 Browser

- 브라우저에서는 아래에 보이는 예시 처럼 URLSearchParams API를 사용합니다. 

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);
Note: URLSearchParams 은 모든 브라우저에서 제공되지 않지만 polyfill을 사용하면 됩니다.

- 대안으로는 qu 라이브러리를 사용하여 데이터를 인코딩시키는 방법입니다.

const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));

@11-2 ES6

import qs from 'qs';
const data = { 'bar': 123 };
const options = {
  method: 'POST',
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
  data: qs.stringify(data),
  url,
};
axios(options);

@11-3 Node.js

- Node.js에서는 다음과 같이 querystring 모듈을 사용합니다. 

const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

- qs 라이브러리를 사용해도 됩니다. 

Note: querystring 메소드는 nested objects를 Stringfy 할 때 이슈가 있는 것으로 알려져 있기 때문에, qs 라이브러리를 이용하는 것이 좋습니다.

#12: Promises

- axios 는 ES6 promise 지원되는 환경을 의존합니다. 만약 ES6 환경이 지원되지 않는다면, polyfill을 해주세요.

#13: TypeScript

- axios는 TypeScript difinition을 포함합니다.  


< 참고자료 >

 

[사이트] #NPM

https://www.npmjs.com/package/axios

 

<Library> axios end

'NPM > Valuable' 카테고리의 다른 글

Axios 뜯어보기  (2) 2023.11.30
Recoil  (0) 2023.11.04
cookie  (0) 2020.12.26
cookie-parser  (0) 2020.08.01
dotenv  (0) 2020.07.26
Comments