【问题标题】:Django >= 3.1 and is_ajaxDjango >= 3.1 和 is_ajax
【发布时间】:2020-12-17 03:51:16
【问题描述】:

HttpRequest.is_ajax() 从 3.1 版开始已弃用。

如果页面是从浏览器请求的,我想返回 html,如果从 javascript 或以编程方式调用,我想返回 JsonResponse

我正在寻求有关如何做到这一点的指导。

https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.HttpRequest.is_ajax

【问题讨论】:

  • 它已被弃用,但尚未移除

标签: django ajax


【解决方案1】:

检查HTTP_X_REQUESTED_WITH标头

def sample_view(request):
    is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'

来自Release Notes of 3.1

HttpRequest.is_ajax() 方法已被弃用,因为它依赖于 jQuery 特定的方式来表示 AJAX 调用,而当前使用倾向于使用 JavaScript Fetch API。根据您的用例,您可以编写自己的 AJAX 检测方法,或者如果您的代码依赖于客户端 Accept HTTP 标头,则使用新的 HttpRequest.accepts() 方法。

【讨论】:

    【解决方案2】:

    有趣的是——无论是弃用消息、文档还是发行说明,都没有说明您“如何使用新的HttpRequest.accepts 方法”来替换HttpRequest.is_ajax

    TLDR:request.accepts("application/json")

    (至少这对我有用。)

    【讨论】:

      【解决方案3】:

      您是否尝试过检查 HttpRequest.headers
      HttpRequest.is_ajax() 取决于 HTTP_X_REQUESTED_WITH 标头。
      因此您可以检查此标头,如果为真,则为 AJAX,否则为来自浏览器的请求。

      HttpRequest.headers['HTTP_X_REQUESTED_WITH']
      

      【讨论】:

        【解决方案4】:

        我按照 arakkal-abu 所说的做了,但我也添加了 'X-Requested-With' 具有相同值的标头 IE。 'XMLHttpRequest'

        按照我的要求,它成功了

        【讨论】:

          【解决方案5】:

          确保在顶部导入它

          import re
          from django.http import JsonResponse
          from django.utils.translation import gettext_lazy as _
          from django.conf.urls import handler404
          

          您可以在您的函数/方法中使用它来确定是来自浏览器还是 ajax 调用

              requested_html = re.search(r'^text/html', request.META.get('HTTP_ACCEPT'))
              if requested_html:
                  # requested from browser, do as per your wish
              # ajax call. Returning as per wish 
              return JsonResponse({
                  'detail': _('Requested API URL not found')
              }, status=404, safe=False)
          

          说明

          如果您请求从浏览器加载页面,您会在该请求的请求标头下的网络选项卡中看到,text/html 位于 requested headers 的开头。

          但是,如果您从浏览器进行 ajax 调用,requested headers 的开头有 */*。如果你附上

          Accept: application/json
          

          在标头中,然后请求的标头变成这个

          由此,您可以了解这些情况下接受标头的不同之处。

          【讨论】:

            【解决方案6】:

            只需检查Content-Type 标头。

            is_ajax = request.META.get("CONTENT_TYPE") == "application/json"
            if is_ajax:
                do_stuff()
            

            【讨论】:

              猜你喜欢
              • 2014-01-05
              • 1970-01-01
              • 2011-12-07
              • 2012-06-20
              • 1970-01-01
              • 2020-03-31
              • 2019-10-06
              相关资源
              最近更新 更多