通过我的AJAX帖子,我需要一些帮助来遵守Django的CSRF保护机制.我按照这里的说明做了:

http://docs.djangoproject.com/en/dev/ref/contrib/csrf/

我复制了他们在该页面上的AJAX示例代码:

http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

我在xhr.setRequestHeader呼叫前打印了getCookie('csrftoken')的内容,并在其中填充了一些数据.我不确定如何验证令牌是否正确,但我很高兴它正在查找并发送一些东西.

但Django仍然拒绝我的AJAX帖子.

以下是我的JavaScript:

$.post("/memorize/", data, function (result) {
    if (result != "failure") {
        get_random_card();
    }
    else {
        alert("Failed to save card data.");
    }
});

以下是我从Django身上看到的错误:

[23/Feb/2011 22:08:29]"POST/memory/HTTP/1.1"403 2332

我肯定我错过了什么,也许很简单,但我不知道是什么.我四处搜索了一下,看到了一些关于通过csrf_exempt decorator关闭CSRF查看的信息,但我觉得这很不吸引人.我已经try 过了,而且效果很好,但如果可能的话,我宁愿让我的帖子按照Django设计的预期工作.

为了以防万一,以下是我的观点的要点:

def myview(request):

    profile = request.user.profile

    if request.method == 'POST':
        """
        Process the post...
        """
        return HttpResponseRedirect('/memorize/')
    else: # request.method == 'GET'

        ajax = request.GET.has_key('ajax')

        """
        Some irrelevent code...
        """

        if ajax:
            response = HttpResponse()
            profile.get_stack_json(response)
            return response
        else:
            """
            Get data to send along with the content of the page.
            """

        return render_to_response('memorize/memorize.html',
                """ My data """
                context_instance=RequestContext(request))

谢谢你的回复!

推荐答案

Real solution

好的,我设法找到了问题所在.它存在于Javascript代码中(正如我在下面建议的).

您需要的是:

$.ajaxSetup({ 
     beforeSend: function(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;
         }
         if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
             // Only send the token to relative URLs i.e. locally.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     } 
});

与官方文件中发布的代码不同:

工作代码来自Django条目:http://www.djangoproject.com/weblog/2011/feb/08/security/

因此,一般的解决方案是:"使用ajaxSetup处理程序,而不是ajaxSend处理程序".我不知道它为什么有效.但这对我来说很管用:)

Previous post (without answer)

事实上,我也遇到了同样的问题.

它发生在更新到Django 1.2.5之后--在Django 1.2.4中,Ajax POST请求没有错误(Ajax没有以任何方式受到保护,但它工作得很好).

和OP一样,我也try 了Django文档中发布的JavaScript片段.我使用的是jQuery 1.5.我还使用了"django.middleware.csrf.CsrfViewMiddleware"中间件.

我试图遵循中间件代码,但我知道它在以下方面失败:

request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')

然后

if request_csrf_token != csrf_token:
    return self._reject(request, REASON_BAD_TOKEN)

此"if"为真,因为"request_csrf_token"为空.

基本上,这意味着没有设置标题.那么这句JS有什么问题吗:

xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));

?

我希望提供的细节将有助于我们解决这个问题:)

Python相关问答推荐

在Python中添加期货之间的延迟

从包含基本数据描述的文本字段中识别和检索特定字符序列

如何在Python中使用ijson解析SON期间检索文件位置?

指示组内的rejected_time是否在creation_timestamp后5分钟内

jit JAX函数中的迭代器

具有多个选项的计数_匹配

运行回文查找器代码时发生错误:[类型错误:builtin_index_or_system对象不可订阅]

替换字符串中的多个重叠子字符串

为什么tkinter框架没有被隐藏?

比较2 PD.数组的令人惊讶的结果

如何使用matplotlib在Python中使用规范化数据和原始t测试值创建组合热图?

使用索引列表列表对列进行切片并获取行方向的向量长度

如何访问所有文件,例如环境变量

切片包括面具的第一个实例在内的眼镜的最佳方法是什么?

pyscript中的压痕问题

如何在UserSerializer中添加显式字段?

如何从列表框中 Select 而不出错?

如何按row_id/row_number过滤数据帧

如何使用正则表达式修改toml文件中指定字段中的参数值

30个非DATETIME天内的累计金额