
Axios의 인터셉터는 요청(request)과 응답(response)을 가로채고, 이를 처리하거나 수정할 수 있는 강력한 기능을 제공한다. 이를 통해 요청 전이나 응답 후에 공통적인 작업을 수행할 수 있으며, 로깅, 인증 토큰 추가, 오류 처리 등을 쉽게 구현할 수 있다. 인터셉터는 Axios 인스턴스에서 사용되며, 다음과 같은 두 가지 유형이 있다.
형태는 axiosInstance.request.use() 의 형태로 쓰이며, response도 동일하다. use에 들어가는 인자는 다음과 같다.
use(onFulfilled, onRejected, options): number
(config: AxiosRequestConfig) => AxiosRequestConfig | Promise<AxiosRequestConfig> 의 타입을 가지는 콜백함수 이며(error: AxiosError): Promise<AxiosError> 의 타입을 가지는 콜백함수이며,AxiosInterceptorOptions 의 타입을 가지며 인터셉터에 대한 추가 옵션을 설정할 수 있는 객체이다. false 이며 비동기적으로 실행된다.true 또는 false를 반환한다. 이 반환값에 따라 인터셉터가 실행 여부를 결정한다.요청 인터셉터는 HTTP 요청이 서버로 전송되기 전에 호출된다. 이 인터셉터를 사용하면, 요청을 수정하거나 특정 작업을 수행할 수 있다. 예를 들어, 요청 헤더에 인증 토큰을 추가하거나, 요청을 로깅할 수 있다.
// 요청 인터셉터 설정
axiosInstance.interceptors.request.use(
(config) => {
// 요청을 보내기 전에 공통적으로 필요한 작업을 이곳에서 수행
// ex) 프론트에서 가지고있는 인증 토큰(쿠키, 세션 등)을 서버에 전송할 때 포함시켜 전송하는 로직
const token = getAuthToken();
if (!!token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
// ex)api를 전송하기 전에 전역 로딩 상태를 세팅하는 로직
setIsLoading(true)
return config;
},
(error) => {
// 요청 오류가 발생한 경우 작업 수행
console.error('Request error:', error);
return Promise.reject(error); // 필요에 따라 다른 오류처리 가능
}
);
응답 인터셉터는 서버에서 응답을 받은 후, 응답이 애플리케이션에 전달되기 전에 호출된다. 이를 통해 응답 데이터를 수정하거나, 오류 처리를 일관되게 수행할 수 있다.
axiosInstance.interceptors.response.use(
(response) => {
// 서버로부터 전달받은 응답을 처리하기 전에 이곳에서 한번 가공할 수 있음
console.log('Response:', response);
// ex)request interceptor 때 세팅해놓은 전역 로딩 상태를 해제하는 로직
setIsLoading(false)
return response;
},
(error) => {
// 응답 오류가 발생한 경우 작업 수행
// 서버에서 제공하는 오류의 상태에 따라서,
// 프론트에서 기존 인증과 관련된 세팅을 리셋하거나 재요청을 하는 등의 작업을 수행할 수 있다.
// ex) 서버로부터 받은 상태 코드값을 통해 화면에 보여줄 에러 표시
if (error.response.status === 401) {
console.log('Unauthorized, logging out...');
}
// 에러가 발생하면, 첫번째 인자의 콜백함수를 타지 않으므로, 로딩상태에 대한 해제도 따로 필요
setIsLoading(false)
return Promise.reject(error);
}
);
Axios의 인터셉터는 체인 형태로 작동한다. 여러 개의 요청 및 응답 인터셉터를 등록할 수 있으며, 각각의 인터셉터는 체인의 다음 인터셉터로 요청/응답을 전달한다.
axiosInstance.interceptors.request.use(firstRequestInterceptor);
axiosInstance.interceptors.request.use(secondRequestInterceptor);
axiosInstance.interceptors.response.use(firstResponseInterceptor);
axiosInstance.interceptors.response.use(secondResponseInterceptor);
// 이 경우, request의 firstRequestInterceptor 가 먼저 호출되고, 그 다음 second... 가 호출된다. response도 마찬가지로 순차적으로 호출된다.
request.use() 와 resposne.use() 는 각각 number 형태의 아이디값을 리턴하는데, 그 아이디값을 eject() 함수의 매개변수로 대입하면 제거가 가능하다.const resInterceptorID = axiosInstance.interceptors.response.use(
(response: AxiosResponse) => {
// 응답 데이터 로그
console.log(response.data);
return response;
},
error => {
return Promise.reject(error);
}
);
// 인터셉터 제거
axiosInstance.interceptors.request.eject(reqInterceptorID);
// response 도 동일
axiosInstance.interceptors.request.clear();
axiosInstance.interceptors.response.clear();