Axios ArrayBuffer Uploads for Binary Protocols
This article explains how the Axios HTTP client handles raw
ArrayBuffer data for binary-based network protocols such as
Protocol Buffers, MessagePack, or custom binary payloads. It covers the
underlying transport mechanisms in both browser and Node.js
environments, required header configurations, proper payload handling,
and how to avoid common serialization pitfalls.
Environment-Specific Transport Mechanisms
Axios automatically adapts how it transmits binary data depending on the execution runtime:
- Browser Environment: Axios utilizes the
XMLHttpRequest(or the Fetch adapter in modern versions). When anArrayBufferis passed as thedataproperty, Axios passes the reference directly to the nativexhr.send()method without serializing it to a string. The browser handles the raw bytes natively over the wire. - Node.js Environment: Axios uses the native
httpandhttpsmodules. In Node.js, anArrayBufferor aTypedArray(such asUint8Array) is internally converted into a Node.jsBufferinstance before being written directly to the writable request stream viareq.write().
Setting Request Headers for Binary Payloads
When transmitting raw binary protocols, you must explicitly define
the Content-Type header. If omitted, Axios or the receiving
server might attempt to infer the MIME type or default to
application/x-www-form-urlencoded or
application/json.
Common headers for binary uploads include:
Content-Type: application/octet-streamfor generic binary streams.Content-Type: application/x-protobuffor Protocol Buffers.Content-Type: application/msgpackfor MessagePack data.
Code Example: Sending an ArrayBuffer
import axios from 'axios';
// Create binary data
const buffer = new ArrayBuffer(8);
const view = new Int32Array(buffer);
view[0] = 42;
view[1] = 84;
async function uploadBinaryData() {
try {
const response = await axios.post('https://api.example.com/binary-endpoint', buffer, {
headers: {
'Content-Type': 'application/octet-stream',
},
// Ensure the response is also handled as binary if needed
responseType: 'arraybuffer',
// Explicit maxBodyLength setting for large binary uploads in Node.js
maxBodyLength: Infinity,
maxContentLength: Infinity,
});
console.log('Binary upload successful:', response.data);
} catch (error) {
console.error('Binary upload failed:', error);
}
}
uploadBinaryData();Handling TypedArrays vs. ArrayBuffers
Axios accepts both ArrayBuffer instances and typed array
views (like Uint8Array, Float32Array, or
DataView).
If you are working with a typed array that represents a sub-slice of a larger buffer, pass the typed array directly or pass the specific sliced buffer:
const uint8Array = new Uint8Array([0x01, 0x02, 0x03, 0x04]);
// Passing TypedArray directly:
await axios.post('/api', uint8Array, {
headers: { 'Content-Type': 'application/octet-stream' }
});
// Or accessing the underlying ArrayBuffer:
await axios.post('/api', uint8Array.buffer, {
headers: { 'Content-Type': 'application/octet-stream' }
});Request Transformations and Interceptors
By default, Axios includes built-in request transformers in
axios.defaults.transformRequest. These default transformers
check whether the data is an ArrayBuffer,
Buffer, FormData, or Stream. When
raw binary data is detected, Axios bypasses JSON stringification and
leaves the payload untouched.
If you use custom Axios instances with modified
transformRequest functions, ensure your custom
transformations do not convert binary payloads into strings or objects
before transmission:
const instance = axios.create({
transformRequest: [
(data, headers) => {
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
return data; // Do not transform binary data
}
return JSON.stringify(data);
}
]
});