【问题标题】:Why does my jquery ajax post to a django view always result in the error callback executing为什么我的 jquery ajax 发布到 django 视图总是导致错误回调执行
【发布时间】:2011-10-07 14:11:16
【问题描述】:

我的 jquery 看起来像这样:

$.ajax({
    url:"/process_values/",
    type: "POST",
    data: {values:['1','2']},
    success:function(response){
        alert("success: " + response);
    },
    error:function (xhr, textStatus, thrownError){
        alert("xhr status: " + xhr.statusText);
    },

});

我的 django 视图如下所示:

@csrf_protect
def process_values(request):
    # do stuff
    print 'complete'
    return HttpResponse("success", mimetype="application/html")

视图正在正确执行,但错误回调总是在它完成时被调用。知道这是为什么吗?

更新:对于那些暗示它是 CSRF 问题的人。不是,我使用标准 javascript 来设置该 cookie,我可以在 django 端的请求中看到令牌。

UPDATE2:我刚刚意识到我的函数中有其他东西调用了这个改变行为的 ajax 调用。我有一个重定向,我使用以下方法编写:

document.location.href="/main/";

当我注释掉这一行时,将调用成功回调。哇,没想到这会有什么不同。有人知道为什么这会导致失败吗?已将此问题移至here,因为这是一个不同的问题。结束这个问题。

【问题讨论】:

  • 你能说什么错误?
  • 该 HttpResponse 方法是否发送回格式正确的 200(成功)状态码?
  • @Sedat - 我怎样才能得到错误? xhr.statusText 显示“错误”。其他参数均未显示错误消息。没有服务器错误。
  • @Greg 不确定格式正确的 200 状态代码是什么样的。我怎么知道?
  • ZincX,你不需要自己手动形成它。 HttpResponse 将能够以一种或另一种方式处理它;您将不得不深入研究它的 API。但是至少要看看发生了什么,打开像 Firebug 这样的调试工具,转到它的“网络活动”选项卡(在 Firebug 中,简称为“网络”),您将能够看到请求的状态代码。

标签: jquery ajax django


【解决方案1】:

你需要在post数据中传递csrf令牌,或者使视图@csrf_exempt

你可以这样做:

$.ajax({
    url:"/process_values/",
    type: "POST",
    data: {values:['1','2'], csrfmiddlewaretoken: $("input[name=csrfmiddlewaretoken]").val()},
    success:function(response){
        alert("success: " + response);
    },
    error:function (xhr, textStatus, thrownError){
        alert("xhr status: " + xhr.statusText);
    },

});

【讨论】:

  • 感谢您的回复。我试过@csrf_exempt,也试过你传递csrfmiddlewaretoken的技术。这些都没有任何区别。我已经从 django 文档中设置了一些 javascript 来修复 csrf 令牌问题。所以,我不认为我遇到的问题与 csrf 令牌有关。
【解决方案2】:

这里的问题是我需要设置 location.href="/main/";在我的成功函数回调中。在导致错误的 ajax 调用期间页面被重定向。

【讨论】:

    【解决方案3】:

    您需要从 Django 1.2.5 开始将 CSRF 令牌添加到您的请求中,以填补安全漏洞。

    Django 人员已经发布了此here 的推荐代码,这是我建议使用的。

    这里是完整的代码粘贴,适合懒人。确保这段代码运行一次(来自全局 JS 文件或其他),然后你就不必担心它了:

    $(document).ajaxSend(function(event, xhr, settings) {
        function getCookie(name) {
            var cookieValue = null;
            if (document.cookie && document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
        function sameOrigin(url) {
            // url could be relative or scheme relative or absolute
            var host = document.location.host; // host + port
            var protocol = document.location.protocol;
            var sr_origin = '//' + host;
            var origin = protocol + sr_origin;
            // Allow absolute or scheme relative URLs to same origin
            return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
                (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
                // or any other URL that isn't scheme relative or absolute i.e relative.
                !(/^(\/\/|http:|https:).*/.test(url));
        }
        function safeMethod(method) {
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
    
        if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2014-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多