【问题标题】:Django request.is_ajax returning falseDjango request.is_ajax 返回 false
【发布时间】:2012-01-25 03:20:42
【问题描述】:

我正在使用 Django + jQuery 测试 ajax。我的观点是:

def ajax_test(request):
    if request.is_ajax():
        message = "This is ajax"
    else:
        message = "Not ajax"
    return HttpResponse(message)

这在我的模板中:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script type="text/javascript" src="{{ STATIC_URL }}js/jquery-1.6.4.js"></script>
</head>
<body>
<script>
$.get("/ajax_test", function(data) {
    alert(data);
    });
});
</script>
</body>
</html>

我的问题是 - 为什么这会将“非 ajax”返回到我的 html 页面?

【问题讨论】:

  • 请注意,is_ajax 在 Django 3.1 中已弃用,将在以后的版本中删除。

标签: ajax django


【解决方案1】:

我不知道你怎么了。我测试并收到了一条好消息:This is ajax。我的代码:

urls.py

url(r'^$', 'myapp.views.home', name='home'),
url(r'^ajax_test/$', 'myapp.views.ajax_test', name='ajax_test'),

views.py

def home(request):
    return render_to_response('home.html', {},
                          context_instance=RequestContext(request))

def ajax_test(request):
    if request.is_ajax():
        message = "This is ajax"
    else:
        message = "Not ajax"
    return HttpResponse(message)

templates/home.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
    $(document).ready(function () {
        $.get("/ajax_test/", function (data) {
            alert(data);
        });
    });
</script>
</body>
</html>

【讨论】:

  • 查看您的代码,我意识到我的错误是我需要两个视图。一种用于模板 (home.html),另一种由 ajax 函数调用 (ajax_test.html)。当我调整我的代码以使其工作时,我得到了想要的结果。我不确定是否总是需要对视图进行这种分离,但它对我有用并且看起来合乎逻辑。
【解决方案2】:

看起来像is_ajax 只是检查HTTP_X_REQUESTED_WITH(在HTTP 中看起来像X-Requested-With)标头。如果它等于XMLHttpRequest,我们就有了一个ajax查询。

所以现在很容易追踪这个标题的命运:

  1. 查看初始 HTTP 请求(使用浏览器的调试插件、Wireshark、tcpdump 或您喜欢的任何其他工具)并查看它是否具有正确的 HTTP_X_REQUESTED_WITH 标头。如果不是,则问题出在 jQuery(或您的脚本)上。

  2. 正如 Daniel Roseman 所说,在重定向期间标头可能会丢失(我自己还没有看到这个,但几乎可以肯定它是可能的)。在这种情况下,您将看到两个(或更多)链接的 HTTP 请求,其中一个将缺少 HTTP_X_REQUESTED_WITH 标头。在这种情况下,问题可能出在网络服务器的配置或重定向本身(如果您的代码生成重定向响应,您可能必须摆脱它或手动中继标头)。

  3. 此外,HTTP 代理可以剪切标头。在这种情况下,您可以通过流量检查器或request.environ(环境变量非常混乱,但 HTTP 标头也在那里)查看服务器端的 HTTP 请求。

【讨论】:

  • 对我来说,大写字母不起作用,这有效:{ 'X-Requested-With': 'XMLHttpRequest', }
  • 确实,我只是复制了 Django 看到的密钥(来自 django/http/request.py),却忘记了它可能会被损坏并且在网络上看起来会有所不同。
  • 谢谢。这就是问题的根源。使用 Axios 我必须执行以下操作:axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
【解决方案3】:

可能您已经打开了 APPEND_SLASH(默认设置),并且 Django 正在从 /ajax_test 重定向到 /ajax_test/ 但不保留相关的标头。最好首先请求带有斜线的版本。

【讨论】:

  • 对不起 - 这没有任何区别。
  • 嗯,我很难过,我害怕。也许尝试将请求标头转储到日志中,看看发生了什么?
【解决方案4】:

将我的代码调整为以下内容:

views.py:

def index(request):
    return render_to_response('index.html',
                            locals(), context_instance=RequestContext(request)) 

def ajax_test(request):
    if request.is_ajax():
        message = "This is ajax"
    else:
        message = "Not ajax"
    return HttpResponse(message)

urls.py:

urlpatterns = patterns('',   
    #    root
    url(r'^$', views.index, name='index'), 
    #    ajax
    url(r'^ajax_test/$', views.ajax_test, name='ajax_test'),
) 

模板:

 ...
 <script type="text/javascript">
 $(document).ready( function() {
     $.get("/ajax_test/", function(data) {
        alert(data);
     });
 });
 </script>

【讨论】:

    【解决方案5】:

    尝试使用其他版本的jQuery...可能问题出在js中...

    例如:

    http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js

    【讨论】:

      【解决方案6】:

      在您的.get 调用中,您必须指定 CSRF 令牌。我不知道这是否是问题,但应该有所帮助。

      .get(..., function(data) {
      
          (...)
          data: { csrfmiddlewaretoken: '{{ csrf_token }}',
          (...)
      })
      

      【讨论】:

      • 不正确或缺失的csrf token会返回403,这与is_ajax无关
      • 如果您从后端获取数据,则不需要 csrf_token,仅在 post 时需要
      猜你喜欢
      • 2014-08-13
      • 2012-11-13
      • 2017-07-20
      • 1970-01-01
      • 2020-04-06
      • 2014-01-10
      • 2020-05-09
      • 2018-05-12
      • 2018-01-22
      相关资源
      最近更新 更多