2

I have a single page js app and I'm sending custom headers to my server containing logs, but i need to control the size of those headers because my server won't accept requests larger then 8k.

My solution thus far was to intercept all outgoing ajax request from my application.

I'm using jQuery Global Ajax Events, particularly ajaxSend to intercept all requests. I cannot use beforeSend because that is a local event.

I can't seem to access the request headers in the callback. I need to read all request's header and cut down the logs header if it's too large.

alexandru.topliceanu
  • 2,364
  • 2
  • 27
  • 38
  • check out this answer: http://stackoverflow.com/questions/7686827/how-can-i-add-a-custom-http-header-to-ajax-request-with-js-or-jquery – Connor Leech Oct 15 '15 at 00:19

1 Answers1

4

You want to use beforeSend to modify the request before it is being sent. This is all covered in the documentation you've linked to.

The global ajaxSend event will not help you tamper with the request. The closest thing to global you can get would be to is call ajaxSetup, passing a beforeSend option to be default for all subsequent ajax calls.


There appears to be no simple way of getting request headers from an XMLHttpRequest object. Since I assume you're setting your logging headers yourself, however, you might be able to hook into the setting of these headers, and store an accessible reference to them:

XMLHttpRequest.prototype.readableHeaders = {};
XMLHttpRequest.prototype.proxiedSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
    this.proxiedSetRequestHeader(header, value);
    this.readableHeaders[header] = value;
};

In this manner, you should be able to directly inspect the jqXHR.readableHeaders object for your specific logging header, in beforeSend, and call setRequestHeader once more, to truncate the string, if needed.

To retrieve the headers you need access to the underlying instance of XMLHttpRequest from jqXHR object. Use xhr() function to retrieve the instance.

$.ajaxSetup({
  beforeSend: function (jqXHR, settings) {
    console.log( settings.xhr().readableHeaders );
  }
});
alexandru.topliceanu
  • 2,364
  • 2
  • 27
  • 38
David Hedlund
  • 128,221
  • 31
  • 203
  • 222
  • Thanks David, however i want to intercept **all requests**, `beforeSend` is a local ajax event, that's why i'm using `ajaxSend` – alexandru.topliceanu Sep 27 '12 at 11:09
  • @alexandru.topliceanu: ah, sorry. You can use `ajaxSetup` to make a specific `beforeSend` listener default for all requests; see my updated answer. – David Hedlund Sep 27 '12 at 11:36
  • Great, but i still have to access the headers to modify them. `beforeSend` gets called with `jqXHR` and `settings` as params, none of them seem to allow me to retrive request headers. i.e. I can use `jqXHR.setRequestHeader()` to set a header but how do i read all headers. – alexandru.topliceanu Sep 27 '12 at 11:48
  • 1
    @alexandru.topliceanu: tricky one! I wasn't aware that the header collection wasn't readily accessible from the xhr. See my second edit, for a suggested workaround. – David Hedlund Sep 27 '12 at 12:05
  • it did work. However, one cannot directly access `readableHeaders` from a jqXHR instance. So you have to `xhr` method that returns the original XMLHttpRequest object. – alexandru.topliceanu Sep 27 '12 at 13:35
  • This is not a good solution. `XMLHttpRequest.prototype.readableHeaders = {};` adds `readableHeaders` map to the `prototype` and not the `instance`. After N number of requests, this map will contain the headers of all N requests instead of the latest one. – Owais Lone Nov 07 '14 at 12:08