Vivek Jha
Vivek Jha

Reputation: 1590

How to determine if it is an AJAX request in Flask

I am planning to use same templates (Jinja 2) for AJAX and normal requests. If it is an AJAX request I will not use extends and for normal request extends would be used for extending the base template.

My problem is, how do I differentiate between a normal and an AJAX request? Is there any way I can introspect the request object to determine whether the incoming request is AJAX based or a normal request?

Upvotes: 3

Views: 1070

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124100

You can't reliably detect if the request was made via AJAX. Some Javascript libraries may set the X-Requested-With header to XMLHttpRequest, but since X-Requested-With is not part of the default set of headers that CORS permits, it is falling out of favour.

In older versions of Flask (before version 1.x), request.is_xhr was provided to detect if this header is present and set to XMLHttpRequest, the defacto API for AJAX requests before the introduction of the Fetch API:

True if the request was triggered via a JavaScript XMLHttpRequest. This only works with libraries that support the X-Requested-With header and set it to XMLHttpRequest. Libraries that do that are prototype, jQuery and Mochikit and probably some more.

Example:

{% if not request.is_xhr %}
    {% extends "base.html" %}
{% endif %}

or

{% extends "base.html" if not request.is_xhr else "ajax.html" %}

In newer versions you'd have to check for the header manually:

{% if request.headers.get("X-Requested-With") != "XMLHttpRequest" %}
    ...
{% endif %}

If you are trying to determine to serve JSON instead of HTML, a more reliable method might be to check if the Accept header includes application/json, via the accept_json property of the request.accept_mimetypes object:

# in Python code, in your view, for example:
if request.accept_mimetypes.accept_json:
    ...

Upvotes: 4

Related Questions