Axios란?
Axios는 자바스크립트 위에서 동작하는 HTTP(S) Request Library입니다. 자바스크립트 위에서 돌아간다는 것은 프론트엔드와 백엔드에서도 사용할 수 있다는 것이므로, 한 번 사용법을 익혀두면 HTTP 요청에 대해서는 더 이상 고민할 것이 없어집니다. 다만, 사용법을 아는 것과 사용법을 이해하는 것은 차이가 꽤 크죠. 여기서는 HTTP 메세지 구조와 연관지어 Axios의 사용법을 이해하여 보겠습니다.
Request
요청
HTTP 요청 메세지의 첫 번째, 두 번째 라인은 다음 정보를 포함하고 있어야 합니다.
- 요청 메서드
- 요청 경로명
- 호스트 주소
GET :
GET /robots.txt HTTP/1.1
Host: naver.comawait Axios({
method: "GET",
url: "https://naver.com/robots.txt",
});POST :
POST / HTTP/1.1
Host: comic.naver.comawait Axios({
method: "POST",
url: "https://comic.naver.com",
});파라미터
부가적인 요청 데이터를 전달할 수 있게 도와줍니다. 경로명 뒷 부분에서 ?으로 시작하여 &으로 분리되고 = 기호로 Key-Value가 연결된 형태입니다. 영어 알파벳이 아닌 문자들은 Percent Character로 인코딩됩니다.
https://search.naver.com/search.naver?query=안녕&ie=utf8GET /search.naver?query=%EC%95%88%EB%85%95&ie=utf8 HTTP/1.1
Host: search.naver.comAxios에서 params 객체를 명시적으로 전달하여, 추가적인 파라미터를 설정할 수 있습니다.
await Axios({
method: "GET",
url: "https://search.naver.com/search.naver",
params: {
ie: "utf8",
query: "안녕",
},
});헤더
부가적인 연결 데이터를 전달할 수 있게 도와줍니다. 두 번째 줄부터 개행으로 분리되고 :기호로 Key-Value가 연결된 형태입니다. 예를 들어, 다음과 같은 관리자 페이지를 가정해봅시다.
http://localhost:4000/admin관리자 페이지 이하에서 발생하는 모든 커넥션은 권한 인증이 필수적으로 요구되는데, 이러한 역할을 하는 추가적인 키값(여기서는 Access-Token)을 헤더에 넣어 관리할 수 있습니다.
GET /admin HTTP/1.1
Host: localhost:4000
Access-Token: 54321Axios에서 headers 객체를 명시적으로 전달하여, 추가적인 헤더를 설정할 수 있습니다.
await Axios({
method: "GET",
url: "https://search.naver.com/search.naver",
headers: {
"Access-Token" : 54321
},
});헤더를 사용하지 않고 전부 파라미터에 넣어버리면 되지 않느냐는 질문이 있을 수 있는데, 관례적으로 파라미터는 어떤 데이터를 원하는지에 대한 정보이고, 관례적으로 헤더는 어떤 연결을 수립할 것인지에 대한 부가적인 정보입니다. 물론 이것은 관례적인 것이라 강제성은 없습니다.
바디
요청 메시지에 큰 데이터를 담아 전달할 수 있습니다. 요청 메세지의 하단부에 정의되며 Content-Type 헤더값에 따라 해석하는 방법이 다르기 때문에, 송신측과 수신측이 서로 동일한 컨텐츠 타입을 사용해야 합니다. 여기서는 x-www-form-urlencoded와 form-data 타입에 대해서만 설명합니다.
x-www-form-urlencoded
풀네임은 application/x-www-form-urlencoded입니다. &으로 분리되고 = 기호로 Key-Value가 연결된 형태입니다. 영어 알파벳이 아닌 문자들은 Percent Character로 인코딩됩니다. 바디 분자열의 크기를 Content-Length 헤더에 명시해야 합니다.
POST / HTTP/1.1
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
say=Hi&to=MomAxios에서 data 객체를 명시적으로 전달하여, 바디를 설정할 수 있습니다.
await axios({
method: "POST",
url: `foo.com`,
headers: {
"Content-Type" : "application/x-www-form-urlencoded",
// "Content-Length"은 자동으로 계산되어 삽입된다.
},
data: {
say:"hi",
to:"mom"
},
});form-data
풀네임은 multipart/form-data입니다. boundary로 구분되는 Key-Value 튜플 입니다. 각 Value는 문자열 또는 파일을 가르킬 수 있습니다. 파일 업로드와 같은 상황에서 주로 사용됩니다.
POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="--xxx"
--xxx
Content-Disposition: form-data; name="field1"
value1
--xxx
Content-Disposition: form-data; name="field2"; filename="example.txt"
value2
--xxxdata 객체를 명시적으로 전달하여 바디를 설정하는 것은 같습니다. 하지만 데이터를 직접 생성하는 것 보다는 FormData 라이브러리를 사용하는 것이 좋습니다.
$ npm install form-data//
// FormData 생성
const formData = new FormData();
formData.append("text", STRING_OBJECT);
formData.append("file", READ_STREAM_OBJECT);
//
//
await axios({
method: "POST",
url: `https://www.tistory.com/apis/post/attach`,
headers: {
//
// form-data headers with boundary
...formData.getHeaders(),
},
data: formData,
});파일을 업로드하기 위해서는 Read Stream을 인자로 전달해야 합니다. 로컬 파일을 업로드하려면 fs을 사용하고, 인터넷에 있는 파일을 업로드하려면 Axios의 반환형식을 stream으로 하여 데이터를 읽어오면 됩니다.
const filePath = "https://www.naver.com/favicon.ico";
const formData = new FormData();
let readStream;
if (filePath.startsWith("http")) {
//
// 인터넷에 있는 파일을 업로드
readStream = (await axios({
method: "GET",
url: filePath,
responseType: "stream",
})).data
} else {
//
// 로컬에 있는 파일을 업로드
readStream = fs.createReadStream(filePath);
}
formData.append("uploadedfile", readStream);Response
반환형식 변경
Axios는 Response Message를 읽어 특정한 포맷으로 변환해줍니다. responseType 옵션을 지정하면 어떤 포맷으로 변환할지 설정할 수 있습니다.
export type ResponseType =
| 'arraybuffer'
| 'blob'
| 'document'
| 'json'
| 'text'
| 'stream'await axios({
method: "GET",
url: "https://naver.com",
responseType: "stream",
})
).data;리다이렉트 방지
기본적으로 Axios는 리다이렉트 상태코드인 302를 만나면, 다시 리다이렉트된 주소로 요청을 시도합니다. 이것을 막으려면 maxRedirects를 0으로 설정하면 됩니다.
await Axios({
method: "GET",
url: "...",
//
// 리다이렉트 방지
maxRedirects: 0,
});유효 상태코드 변경
기본적으로 Axios는 오류 상태코드인 4xx, 5xx, ...를 만나면 에러를 발생시킵니다. 하지만 에러가 발생하는게 당연한 상황인 경우가 있을겁니다. 유효한 상태코드를 변경하려면 validateStatus(stat)를 설정하면 됩니다. 이 함수가 false일 때만 에러가 발생합니다.
await Axios({
method: "GET",
url: "...",
maxRedirects: 0,
validateStatus: function (stat: number) {
return stat === 302;
},
});쿠키값 가져오기
서버가 클라이언트 측에 쿠키를 설정하기 위해서는 응답 메세지 헤더에 set-cookie를 설정해야 합니다.
Set-Cookie: x=1; HttpOnly; Path=/
Set-Cookie: y=2; HttpOnly; Path=/
Set-Cookie: z=3; HttpOnly; Path=/이것을 역이용하면 응답 메세지 헤더에서 서버가 설정하고자 하는 쿠키 목록들을 가져올 수 있습니다.
const res = await Axios({
...
});
const cookies : string[] = res["headers"]["set-cookie"];
// cookies[0] = "x=1; HttpOnly; Path=/"
// cookies[1] = "y=2; HttpOnly; Path=/"
// cookies[2] = "z=3; HttpOnly; Path=/"