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

Oct 29, 2019 · Updated: Jul 12, 2021 · by Tim Kamanin

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 !

Hey, if you've found this useful, please share the post to help other folks find it:

There's even more:

Subscribe for updates

  • via Twitter: @timonweb
  • old school RSS:
  • or evergreen email ↓ ↓ ↓