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
- Header Verification: Always inspect
response.headers['content-encoding']before attempting decompression. If an API ignores theAccept-Encoding: gziprequest header and returns plaintext, runninggunzipwill throw anincorrect header checkerror. - Browser Limitations: In a browser environment,
decompression is handled automatically at the network layer by the
browser engine itself; manual
zlibdecompression is typically only applicable in Node.js runtime environments.