18

Is there a way to check if a request is AJAX in Python?

The equivalent of PHP's $_SERVER['HTTP_X_REQUESTED_WITH'] == 'xmlhttprequest'?

Abdurahman
  • 628
  • 8
  • 16
Yarin
  • 173,523
  • 149
  • 402
  • 512

4 Answers4

35

If the AJAX framework sets the X-Requested-With header in its requests, then you will be able to use that header to detect AJAX calls. It's up to the client-side framework to do this.

Getting hold of the HTTP headers depends on your Python framework of choice. In Django, the request object has an is_ajax method you can use directly.

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
4

is_ajax() is deprecated since Django 3.1 (as of 28th May, 2021) as they stated that it depends on jQuery ways of sending request but since people use fetch method a lot to make call Ajax calls, it has become unreliable in many cases.

Usually, text/html is requested in the header in the first option in the browser when it just the loads the page. However, if you were making API call, then it would become */* by default, if you attach Accept: application/json in the headers, then it become

application/json

So, you can check easily if the request is coming from ajax by this

import re # make sure to import this module at the top

in your function

requested_html = re.search(r'^text/html', request.META.get('HTTP_ACCEPT'))
if not requested_html:
    # ajax request it is
Koushik Das
  • 9,678
  • 3
  • 51
  • 50
0

Just in case someone can find this useful, the Sec-Fetch-Dest can hint if the request is an ajax call or not.

So one could have something like this:

is_ajax_call = all(
                    request.headers.get("Sec-Fetch-Dest", "")
                    not in secFetchDest for secFetchDest in ["document", "iframe"]
                )
Painy James
  • 805
  • 2
  • 13
  • 26
0

Check this how to check if request is ajax in turbogears

also this for how to do this in Django(it depends in your framework): How to check contents of incoming HTTP header request

Community
  • 1
  • 1
Abdurahman
  • 628
  • 8
  • 16