How to make Django request.is_ajax() work with JS fetch()

29 Oct · by Tim Kamanin · 1 min read

Django's request object has a nifty little method is_ajax. It allows determining whether a request comes from a JS framework (aka old-school ajax). While it works fine with some JS libraries, including the venerable jQuery, it won't work with modern JS native fetch API out of the box.

The reason

If we'll look into request guts:

def is_ajax(self):
  return self.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'

we'll see that in order to announce request as ajax our method expects a HTTP_X_REQUESTED_WITH header to be sent with the request. The value of the header should equal XMLHttpRequest.

The solution

Mkay, that means we just need to slap HTTP_X_REQUESTED_WITH: 'XMLHttpRequest' onto fetch config, and we're done, right? Wrong, it won't work, because instead of calling it HTTP_X_REQUESTED_WITH you have to name it X-Requested-With and only then it'll click. Weird, huh?

Here's a working example of how you do that:

fetch('/submit-form', {
  method: "POST",
  ...
  headers: {
    "X-Requested-With": "XMLHttpRequest"
  },
  ...
});

I deliberately left out other bits of a fetch request that might differ depending on your situation. And yes, we're done here. ☕️ time !

Want to get more 🔥 tips like this one?

Subscribe to get notified about new dev tutorials