Django request.is_ajax 返回 false

Posted

技术标签:

【中文标题】Django request.is_ajax 返回 false【英文标题】:Django request.is_ajax returning 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 中已弃用,将在以后的版本中删除。 【参考方案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查询。

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

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

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

    此外,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 时需要

以上是关于Django request.is_ajax 返回 false的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django 实现 ajax 表单

使用 bootstrap 和 django 的异步表单

django views怎么返回json

django在view返回结果没问题是中文,在模板返回的是unicode编码为啥

使用Django返回helloworld

使用Django返回helloworld