Sanitize URL Query Parameters in Axios

Sanitizing URL query parameters before sending HTTP requests with Axios is essential for preventing malformed requests, avoiding injection vulnerabilities, and ensuring API reliability. This guide covers the most effective methods to clean, validate, and encode query parameters in Axios, including custom serialization, native JavaScript APIs, schema validation, and Axios request interceptors.

1. Using Axios paramsSerializer with qs

Axios allows you to define a custom paramsSerializer to control how query objects are converted into a query string. Pairing this with the qs library provides fine-grained control over encoding, handling null values, and array formats.

import axios from 'axios';
import qs from 'qs';

const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  paramsSerializer: {
    serialize: (params) => {
      // Clean and serialize parameters
      return qs.stringify(params, {
        skipNulls: true, // Remove keys with null values
        encode: true,    // Percent-encode URI components
        arrayFormat: 'brackets',
      });
    },
  },
});

// Outbound request with automatic sanitization
apiClient.get('/search', {
  params: {
    query: 'hello world & safe',
    filter: null, // Stripped automatically
    tags: ['web', 'security'],
  },
});

2. Cleaning Parameters with Native JavaScript Utilities

You can build a helper utility to clean inputs by removing null, undefined, or empty string values and trimming excessive whitespace before assigning them to the Axios params object.

function sanitizeParams(rawParams) {
  return Object.entries(rawParams).reduce((acc, [key, value]) => {
    if (value === null || value === undefined || value === '') {
      return acc;
    }

    if (typeof value === 'string') {
      acc[key] = value.trim();
    } else {
      acc[key] = value;
    }

    return acc;
  }, {});
}

// Usage with Axios
const cleanParams = sanitizeParams({
  search: '  sanitized term  ',
  page: 1,
  category: '',
  invalidField: undefined,
});

axios.get('https://api.example.com/items', { params: cleanParams });

3. Native URLSearchParams Construction

The native URLSearchParams interface automatically ensures standard percent-encoding of query keys and values.

const rawData = {
  keyword: 'axios & params',
  status: 'active',
};

const searchParams = new URLSearchParams();

Object.entries(rawData).forEach(([key, value]) => {
  if (value !== null && value !== undefined) {
    searchParams.append(key, String(value).trim());
  }
});

axios.get('https://api.example.com/data', { params: searchParams });

4. Schema-Based Validation with Zod

For strict type safety and structured sanitization, schema validation libraries like Zod can strip unknown keys, cast data types, and enforce validation rules before dispatching the request.

import { z } from 'zod';
import axios from 'axios';

const QuerySchema = z.object({
  search: z.string().trim().min(1),
  page: z.number().int().positive().default(1),
  sortBy: z.enum(['date', 'popularity']).default('date'),
});

function fetchProducts(rawParams) {
  // Parses, transforms, and removes undeclared properties
  const validatedParams = QuerySchema.parse(rawParams);

  return axios.get('https://api.example.com/products', {
    params: validatedParams,
  });
}

5. Centralized Sanitization via Axios Interceptors

To enforce parameter sanitization globally across all requests without duplicating logic, apply an Axios request interceptor.

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://api.example.com',
});

api.interceptors.request.use((config) => {
  if (config.params) {
    const sanitized = {};
    for (const [key, value] of Object.entries(config.params)) {
      if (value !== null && value !== undefined && value !== '') {
        sanitized[key] = typeof value === 'string' ? value.trim() : value;
      }
    }
    config.params = sanitized;
  }
  return config;
}, (error) => {
  return Promise.reject(error);
});