Reputation: 1590
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
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