- Spec files
npm-axios
Describes: pkg:npm/axios@0.30.x
- Description
- Promise based HTTP client for the browser and node.js
- Author
- tessl
- Last updated
interceptors.md docs/
1# Interceptors23Request and response interceptors provide a middleware system for transforming requests before they're sent and responses before they're handled by your code. This enables powerful patterns like automatic authentication, request/response logging, error handling, and data transformation.45## Capabilities67### Request Interceptors89Transform or modify requests before they are sent to the server.1011```javascript { .api }12/**13* Add request interceptor14* @param onFulfilled - Function to transform successful requests15* @param onRejected - Function to handle request errors16* @param options - Optional interceptor configuration17* @returns Interceptor ID for later removal18*/19axios.interceptors.request.use(20onFulfilled?: (config: AxiosRequestConfig) => AxiosRequestConfig | Promise<AxiosRequestConfig>,21onRejected?: (error: any) => any,22options?: AxiosInterceptorOptions23): number;24```2526**Usage Examples:**2728```javascript29// Add authentication token to all requests30axios.interceptors.request.use(31(config) => {32const token = localStorage.getItem('authToken');33if (token) {34config.headers.Authorization = `Bearer ${token}`;35}36return config;37},38(error) => {39return Promise.reject(error);40}41);4243// Log all outgoing requests44axios.interceptors.request.use(45(config) => {46console.log(`Making ${config.method?.toUpperCase()} request to ${config.url}`);47console.log('Request config:', config);48return config;49}50);5152// Async request transformation53axios.interceptors.request.use(54async (config) => {55// Get fresh token asynchronously56const token = await getValidToken();57config.headers.Authorization = `Bearer ${token}`;58return config;59}60);6162// Conditional interceptor with runWhen63axios.interceptors.request.use(64(config) => {65config.headers['X-Request-Source'] = 'web-app';66return config;67},68null,69{70runWhen: (config) => config.url?.includes('/api/') === true71}72);73```7475### Response Interceptors7677Transform or handle responses before they reach your application code.7879```javascript { .api }80/**81* Add response interceptor82* @param onFulfilled - Function to transform successful responses83* @param onRejected - Function to handle response errors84* @param options - Optional interceptor configuration85* @returns Interceptor ID for later removal86*/87axios.interceptors.response.use(88onFulfilled?: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>,89onRejected?: (error: any) => any,90options?: AxiosInterceptorOptions91): number;92```9394**Usage Examples:**9596```javascript97// Transform response data98axios.interceptors.response.use(99(response) => {100// Extract data from wrapper object101if (response.data && response.data.result) {102response.data = response.data.result;103}104return response;105},106(error) => {107return Promise.reject(error);108}109);110111// Handle token expiration globally112axios.interceptors.response.use(113(response) => response,114async (error) => {115if (error.response?.status === 401) {116// Token expired, try to refresh117try {118const newToken = await refreshAuthToken();119localStorage.setItem('authToken', newToken);120121// Retry original request with new token122const originalRequest = error.config;123originalRequest.headers.Authorization = `Bearer ${newToken}`;124return axios(originalRequest);125} catch (refreshError) {126// Refresh failed, redirect to login127window.location.href = '/login';128return Promise.reject(refreshError);129}130}131return Promise.reject(error);132}133);134135// Log response details136axios.interceptors.response.use(137(response) => {138console.log(`Response ${response.status} from ${response.config.url}`);139console.log('Response time:', Date.now() - response.config.metadata?.startTime);140return response;141},142(error) => {143console.error('Request failed:', error.message);144return Promise.reject(error);145}146);147```148149### Interceptor Management150151Manage (remove, clear, inspect) existing interceptors.152153```javascript { .api }154/**155* Remove request interceptor by ID156* @param id - Interceptor ID returned from use()157*/158axios.interceptors.request.eject(id: number): void;159160/**161* Remove response interceptor by ID162* @param id - Interceptor ID returned from use()163*/164axios.interceptors.response.eject(id: number): void;165166/**167* Clear all request interceptors168*/169axios.interceptors.request.clear(): void;170171/**172* Clear all response interceptors173*/174axios.interceptors.response.clear(): void;175176/**177* Iterate over all registered request interceptors178* @param fn - Function called for each interceptor179*/180axios.interceptors.request.forEach(fn: (interceptor: any) => void): void;181182/**183* Iterate over all registered response interceptors184* @param fn - Function called for each interceptor185*/186axios.interceptors.response.forEach(fn: (interceptor: any) => void): void;187```188189**Usage Examples:**190191```javascript192// Add interceptor and store ID193const requestInterceptorId = axios.interceptors.request.use(194(config) => {195config.headers['X-Custom-Header'] = 'value';196return config;197}198);199200// Remove interceptor later201axios.interceptors.request.eject(requestInterceptorId);202203// Clear all request interceptors204axios.interceptors.request.clear();205206// Clear all response interceptors207axios.interceptors.response.clear();208209// Temporary interceptor for specific operation210const tempInterceptor = axios.interceptors.response.use(211(response) => {212console.log('Temporary logging active');213return response;214}215);216217// Perform operations with temporary interceptor218await performSomeOperations();219220// Remove temporary interceptor221axios.interceptors.response.eject(tempInterceptor);222223// Clear all interceptors for cleanup224axios.interceptors.request.clear();225axios.interceptors.response.clear();226```227228### Interceptor Configuration Options229230Advanced interceptor configuration for specialized behavior.231232```javascript { .api }233interface AxiosInterceptorOptions {234/** Whether the interceptor should run synchronously (default: false) */235synchronous?: boolean;236/** Function to determine if interceptor should run for a specific request */237runWhen?: (config: AxiosRequestConfig) => boolean;238}239```240241**Usage Examples:**242243```javascript244// Synchronous interceptor (runs immediately, not in Promise chain)245axios.interceptors.request.use(246(config) => {247config.headers['X-Timestamp'] = Date.now().toString();248return config;249},250null,251{ synchronous: true }252);253254// Conditional interceptor255axios.interceptors.request.use(256(config) => {257config.headers['X-API-Version'] = '2.0';258return config;259},260null,261{262runWhen: (config) => {263// Only run for API calls, not static assets264return config.url?.startsWith('/api/') ?? false;265}266}267);268269// Combined options270axios.interceptors.response.use(271(response) => {272// Fast synchronous response transformation273response.data = response.data?.data || response.data;274return response;275},276null,277{278synchronous: true,279runWhen: (config) => config.responseType !== 'blob'280}281);282```283284### Interceptor Manager Interface285286The interceptor manager objects accessible via `axios.interceptors.request` and `axios.interceptors.response`.287288```javascript { .api }289interface AxiosInterceptorManager<V> {290/**291* Add an interceptor292* @param onFulfilled - Success handler293* @param onRejected - Error handler294* @param options - Configuration options295* @returns Interceptor ID for removal296*/297use<T = V>(298onFulfilled?: (value: V) => T | Promise<T>,299onRejected?: (error: any) => any,300options?: AxiosInterceptorOptions301): number;302303/**304* Remove an interceptor by ID305* @param id - Interceptor ID from use()306*/307eject(id: number): void;308309/**310* Clear all interceptors311*/312clear(): void;313314/**315* Iterate over registered interceptors316* @param fn - Function called for each interceptor317*/318forEach(fn: (interceptor: any) => void): void;319}320```321322## Advanced Interceptor Patterns323324### Request/Response Correlation325326Track requests and responses together using metadata:327328```javascript329// Request interceptor - add timing330axios.interceptors.request.use((config) => {331config.metadata = { startTime: Date.now() };332return config;333});334335// Response interceptor - calculate duration336axios.interceptors.response.use((response) => {337const duration = Date.now() - response.config.metadata.startTime;338console.log(`Request took ${duration}ms`);339return response;340});341```342343### Error Recovery and Retry344345Implement automatic retry logic with exponential backoff:346347```javascript348axios.interceptors.response.use(349(response) => response,350async (error) => {351const config = error.config;352353// Don't retry if we've already retried too many times354if (!config || config.__retryCount >= 3) {355return Promise.reject(error);356}357358// Only retry on network errors or 5xx responses359if (error.code === 'NETWORK_ERROR' || (error.response && error.response.status >= 500)) {360config.__retryCount = config.__retryCount || 0;361config.__retryCount += 1;362363// Exponential backoff delay364const delay = Math.pow(2, config.__retryCount) * 1000;365await new Promise(resolve => setTimeout(resolve, delay));366367return axios(config);368}369370return Promise.reject(error);371}372);373```374375### Instance-Specific Interceptors376377Interceptors on custom instances only affect that instance:378379```javascript380// Create API client with instance-specific interceptors381const apiClient = axios.create({ baseURL: 'https://api.example.com' });382383// This interceptor only affects apiClient requests384apiClient.interceptors.request.use((config) => {385config.headers['X-Client-Version'] = '1.0';386return config;387});388389// This interceptor only affects apiClient responses390apiClient.interceptors.response.use(391(response) => {392// Custom response transformation for this API393return response;394}395);396397// Main axios instance is unaffected398const otherResponse = await axios.get('https://other-api.com/data'); // No X-Client-Version header399```