Axios란?
Axios
는 자바스크립트 위에서 동작하는 HTTP(S) Request Library
입니다. 자바스크립트 위에서 돌아간다는 것은 프론트엔드
와 백엔드
에서도 사용할 수 있다는 것이므로, 한 번 사용법을 익혀두면 HTTP 요청
에 대해서는 더 이상 고민할 것이 없어집니다. 다만, 사용법을 아는 것
과 사용법을 이해하는 것
은 차이가 꽤 크죠. 여기서는 HTTP
메세지 구조와 연관지어 Axios
의 사용법을 이해하여 보겠습니다.
Request
요청
HTTP 요청 메세지
의 첫 번째, 두 번째 라인은 다음 정보를 포함하고 있어야 합니다.
- 요청 메서드
- 요청 경로명
- 호스트 주소
GET :
GET /robots.txt HTTP/1.1
Host: naver.com
await Axios({
method: "GET",
url: "https://naver.com/robots.txt",
});
POST :
POST / HTTP/1.1
Host: comic.naver.com
await Axios({
method: "POST",
url: "https://comic.naver.com",
});
파라미터
부가적인 요청 데이터를 전달할 수 있게 도와줍니다. 경로명 뒷 부분에서 ?
으로 시작하여 &
으로 분리되고 =
기호로 Key-Value
가 연결된 형태입니다. 영어 알파벳이 아닌 문자들은 Percent Character
로 인코딩됩니다.
https://search.naver.com/search.naver?query=안녕&ie=utf8
GET /search.naver?query=%EC%95%88%EB%85%95&ie=utf8 HTTP/1.1
Host: search.naver.com
Axios
에서 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: 54321
Axios
에서 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=Mom
Axios
에서 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
--xxx
data
객체를 명시적으로 전달하여 바디를 설정하는 것은 같습니다. 하지만 데이터
를 직접 생성하는 것 보다는 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=/"