A simple way to do this in vanilla JS is to augment the XMLHTTPRequest.prototype.send
method.
You would do something like
const defaultSend = XMLHTTPRequest.prototype.send;
XMLHTTPRequest.prototype.send = function (data) {
this.setRequestHeader('SOME-CUSTOM-HEADER', 'header-value');
defaultSend.call(this, data);
};
While this works, it's like using a nuke when you need a hammer. It pollutes ALL of the following XHRs run in the context of that particular window. While you could do domain level filtering, but I find that it's not worth the trouble.
If you are using client XHR libraries like axios, they will often provide a better and more contextual way. For example, in case of axios, you could do something like
const client = axios.createClient();
client.interceptors.request.use(config => {
config.headers['SOME-CUSTOM-HEADER'] = 'header-value';
return config;
});
client.get('/some-url', params); // this will have the custom header that you injected
EDIT: One caveat here is that this only affects XHRs, not form submissions or asset calls.