How to Handle Gzip Responses Manually in Axios

Handling gzipped API responses manually in Axios requires disabling Axios's automatic decompression, retrieving the raw binary payload, and decompressing the data using Node.js's built-in zlib module. This approach is essential when working with custom data pipelines, handling corrupt response headers, caching compressed payloads directly, or streaming large compressed datasets.

Step 1: Configure Axios to Prevent Auto-Decompression

By default, Axios automatically decompresses responses in Node.js environments if the server sends a Content-Encoding: gzip header. To handle decompression manually, set the decompress option to false and specify responseType: 'arraybuffer' (or 'stream' for streaming architectures).

const axios = require('axios');

const config = {
  method: 'get',
  url: 'https://api.example.com/data',
  headers: {
    'Accept-Encoding': 'gzip'
  },
  decompress: false, // Disables automatic decompression by Axios
  responseType: 'arraybuffer' // Preserves the raw binary data
};

Step 2: Decompress the Buffer Using zlib

Once you obtain the raw binary buffer from the Axios response, use Node.js's zlib.gunzip (asynchronous) or zlib.gunzipSync (synchronous) to decompress the payload.

const axios = require('axios');
const zlib = require('zlib');
const { promisify } = require('util');

const gunzip = promisify(zlib.gunzip);

async function fetchGzipData() {
  try {
    const response = await axios({
      method: 'get',
      url: 'https://api.example.com/data',
      headers: { 'Accept-Encoding': 'gzip' },
      decompress: false,
      responseType: 'arraybuffer'
    });

    // Check if the response is actually gzipped
    const isGzipped = response.headers['content-encoding'] === 'gzip';

    let decompressedBuffer;
    if (isGzipped) {
      decompressedBuffer = await gunzip(response.data);
    } else {
      decompressedBuffer = response.data;
    }

    // Convert decompressed buffer to string or JSON
    const textData = decompressedBuffer.toString('utf-8');
    const jsonData = JSON.parse(textData);

    return jsonData;
  } catch (error) {
    console.error('Error fetching or decompressing data:', error);
    throw error;
  }
}

Step 3: Decompressing Gzip Streams (Alternative Method)

For memory-efficient handling of large responses, use streams by setting responseType: 'stream' and piping the incoming payload through a zlib.createGunzip() transform stream.

const axios = require('axios');
const zlib = require('zlib');

async function streamGzipData() {
  const response = await axios({
    method: 'get',
    url: 'https://api.example.com/large-data',
    headers: { 'Accept-Encoding': 'gzip' },
    decompress: false,
    responseType: 'stream'
  });

  const gunzipStream = zlib.createGunzip();

  response.data
    .pipe(gunzipStream)
    .on('data', (chunk) => {
      console.log('Received chunk:', chunk.toString('utf-8'));
    })
    .on('error', (err) => {
      console.error('Decompression stream error:', err);
    })
    .on('end', () => {
      console.log('Stream decompression finished.');
    });
}

Key Considerations