Jason22
Jason22

Reputation: 69

Modify headers of only POST XMLHttpRequest

 (function() {
      var send = XMLHttpRequest.prototype.send,
          token = document.getElementsByTagName('meta')['csrf-token'].content;
      XMLHttpRequest.prototype.send = function(data) {
          this.setRequestHeader('X-CSRF-Token', token);
          return send.apply(this, arguments);
      };
  }());
I am intercepting all the calls to append X-CSRF-Token to the request header. Is there a way to limit this just to post calls? Cannot use jQuery.ajaxPrefilter() as it doesn't intercept all the calls I want.

Upvotes: 1

Views: 1231

Answers (2)

Triby
Triby

Reputation: 1757

I couldn't find a way to detect method used for an AJAX call, but you can try:

  • Override open method to verify wich method is used for the call
  • Add a custom property for token
  • On the send method, evaluate that property to add or not the header
(function() {
    var proxied = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function() {
        this.token = (arguments[0].toUpperCase() == 'POST')
            ? document.getElementsByTagName('meta')['csrf-token'].content
            : null;
        return proxied.apply(this, [].slice.call(arguments));
    };
    var send = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = function(data) {
        if(this.token) {
            this.setRequestHeader('X-CSRF-Token', token);
        }
        return send.apply(this, arguments);
    };
})();

I've used this answer for overriding open method.

In strict mode, this.token = ... could fail. If it's your case, just use:

        let token = (arguments[0].toUpperCase() == 'POST')
            ? document.getElementsByTagName('meta')['csrf-token'].content
            : null;
        Object.defineProperty(this, 'token', token);

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

Upvotes: 2

Anton Bakinowsky
Anton Bakinowsky

Reputation: 352

It doesn't look right for me to modify native methods.
I'd rather create some helpers to work with requests.

For example:

// base helper that will be used for any type of requests (POST/GET/PUT/DELETE).

function makeRequest(url, settings) {
  // do what ever you need here to setup a XMLHttpRequest
}
function makePostRequest(url, body) {
    makeRequest(
        example.com, 
        { 
            body, 
            headers: { 'X-CSRF-Token': token } 
        }
    );
}

function makeGetRequest() {...}

function makePostRequest() {...}

function makeDeleteRequest() {...}

As a result you will have useful helpers to work with requests and you don't need to modify XMLHttpRequest prototype.

Upvotes: 0

Related Questions