Node.js httpsAgent and browser fetch adapter TLS interoperability in axios
0 reputation · 27 Sept 2023, 20:10 UTC
0 reputation · 27 Sept 2023, 20:10 UTC
I need axios to apply consistent DNS resolution and certificate validation behavior across Node.js and browser environments. The Node.js HTTP adapter accepts httpAgent and httpsAgent, which can inject custom lookup and TLS logic, but browser adapters based on XHR or fetch do not expose equivalent agent options.
Axios does not appear to normalize transport-layer errors, so ENOTFOUND and certificate failures surface differently depending on the adapter. It is unclear whether a custom adapter is the only supported path for uniform behavior, or whether axios version 1.x provides any abstraction I have missed.
Can axios options normalize DNS and certificate validation across Node.js and browser adapters? If not, is a custom adapter the documented mechanism for achieving consistent TLS semantics?
33775 reputation · 28 Sept 2023, 04:20 UTC
No, Axios does not provide a native abstraction to normalize DNS resolution or certificate validation across Node.js and browser environments. Because Axios acts as a wrapper around environment-specific transport layers (the https module in Node.js and XHR/Fetch in browsers), it is limited by the capabilities of the underlying runtime.
In the Node.js environment, the httpsAgent and httpAgent options allow you to inject an instance of https.Agent. This object provides direct control over the lookup function (for DNS resolution) and the rejectUnauthorized flag (for certificate validation).
Conversely, browser-based adapters using fetch or XHR operate within the browser's security sandbox. Browsers do not expose TLS-level certificate pinning or custom DNS logic to JavaScript to prevent security vulnerabilities like man-in-the-middle attacks. Consequently, an error such as ENOTFOUND in Node.js will typically manifest as a generic TypeError: Failed to fetch in the browser.
Since Axios 1.x does not normalize these semantics, the documented mechanism for achieving consistent behavior is implementing a custom adapter. This allows you to intercept the environment-specific response and normalize it before it reaches your application logic.
process vs. window).TypeErrors or network failures to that same custom schema.import axios from 'axios';
import httpAdapter from 'axios';
const customAdapter = (config) => {
const isNode = typeof process !== 'undefined' & process.versions.node;
const adapter = isNode ? null : null; // simplified
return adapter(config).then(response => response, error => {
return normalizeError(error);
});
};
function normalizeError(error) {
// Map ENOTFOUND and browser fetch failures to a unified constant
if (error.code === 'ENOTFOUND' || error.message.includes('Failed to fetch')) {
error.unifiedCode = 'NETWORK_DNS_ERROR';
}
return error;
}
const instance = axios.create({ adapter: customAdapter });
This approach assumes your goal is application-level consistency. It is important to note that you cannot force the browser to perform custom certificate validation (like ignoring self-signed certs) via Axios; that remains a browser-level security setting. For such cases, the logic must be handled by a proxy or manual browser configuration.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.