Django Ajax“禁止”错误

Posted

技术标签:

【中文标题】Django Ajax“禁止”错误【英文标题】:Django Ajax "FORBIDDEN" error 【发布时间】:2011-09-04 21:40:53 【问题描述】:

我看到人们在尝试发出远程 Ajax 请求时遇到禁止错误的情况,但我正在发出本地请求,并且我的中间件中也打开了 CSRF。

errorThrown 正在返回“禁止”

我认为问题可能是我正在尝试将其发送到普通视图(当前页面)......我不确定我的预处理器是否正在返回视图以重新呈现页面......或者如果它立即返回到我的当前页面。 (不要以为我解释得很好)

希望这能让您充分了解正在发生的事情。感谢任何/所有帮助。

.ajax:

jQuery.ajax(
        type: "POST",
        dataType: "json",
        data: dataString,
        success: function(json) 
              jQuery(".signup").attr('disabled', false);
              $('.success').show();
              console.log(json.message);
        ,
        error: function(jqXHR, textStatus, errorThrown) 
              jQuery(".signup").attr('disabled', false);
              $('.fail').show().append(errorThrown);
              console.log(textStatus);
        

    );

【问题讨论】:

哇,这个问题真的帮了我大忙。谢谢!!! 【参考方案1】:

如果你开启了 csrf,你会得到 403 错误,尝试添加 views.py 看看是不是这个原因:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
view class/method

【讨论】:

我必须恭敬地不同意这个答案。将 CSRF 令牌添加到请求中要比完全从 CSRF 中排除视图要好得多。 @Luke 我支持这个!当然,一旦您知道这是问题所在,请重新添加 CSRF 保护。 除了这个 decotator 的存在是有原因的:在具有大量调用的 AJAX 应用程序上,最好在项目开始时对视图进行保护,否则,您将没有任何东西可以显示给您的客户截止日期。 这个答案很有价值。在将视图从 CSRF 中排除之前,您可能已经添加了一些关于三思而后行的“废话”,但通常在这个答案中没有什么可以“不同意”的。到目前为止,它比关闭 CSRF 中间件,并在“需要的地方”用 CSRF 保护装饰视图要好得多。在浏览器中,您可以沉迷于 cookie 等,但是在编写一个简单的 Web 服务时,它应该可以通过例如访问。 urllib2 没有太多的黑客攻击 - @csrf_exempt 没什么不好!【参考方案2】:

即使请求是针对同一个域的,您也需要 CSRF 令牌。这里有代码可以将 CSRF 令牌添加到您的 AJAX 请求(使用 jQuery):

https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#ajax

此链接指向版本 1.7,如果您使用的是不同版本的 Django,您可以从右下角的浮动菜单中选择您的版本。

【讨论】:

那是专门针对 AJAX 的吗?我已经添加了 CSRF 中间件。 啊,没关系..我现在明白了。我有另一个 JSON 错误,但这无关紧要。谢谢。 值得注意的是链接指向1.3版,此后代码略有更改。 我遇到了同样的问题(ajax 调用时出现 403 错误),按照上面链接的文档中描述的方法是无痛的并修复了它。【参考方案3】:

好吧,如果您仍然需要 CSRF 保护,请阅读我的解决方案。

就我而言,我有一个模板,我不想在其中包含<form></form> 元素。但我仍然想使用 jQuery 发出 AJAX POST 请求。

由于 CSRF cookie 为空,我得到了 403 错误,即使我遵循了 django 文档 (https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/)。解决方案在同一页面中,提到了ensure_csrf_cookie 装饰器。

当我在views.py 顶部添加这个时,我的 CSRF cookie 确实被设置了:

from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie

另外,请注意,在这种情况下,您不需要标记/模板中的 DOM 元素:% csrf_token %

【讨论】:

如果您不在浏览器中并且想在您的第一个请求中发布,该怎么办? (不一定是“AJAX”,而是说 REST)【参考方案4】:

从这里下载 jQuery.Cookie 并包含它:http://plugins.jquery.com/cookie/

然后,添加beforeSend 函数并像这样发送csrf令牌:

jQuery.ajax(
    type: "POST",
    dataType: "json",
    data: dataString,
    beforeSend: function(xhr, settings) 
        xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
    ,
    success: function(json) 
          jQuery(".signup").attr('disabled', false);
          $('.success').show();
          console.log(json.message);
    ,
    error: function(jqXHR, textStatus, errorThrown) 
          jQuery(".signup").attr('disabled', false);
          $('.fail').show().append(errorThrown);
          console.log(textStatus);
    

);

【讨论】:

这是 5 年前提出的问题 我遇到了同样的问题,然后我想发布我的解决方案。我想也许有人可以从中受益。

以上是关于Django Ajax“禁止”错误的主要内容,如果未能解决你的问题,请参考以下文章

Ajax 发布 Django Rest Framework 出现 403 禁止错误

Django 403 禁止错误

Django ajax GET 403(禁止)

Django - 使用 ExtJS 发布 ajax 请求禁止 403

django ajax 发布 403 被禁止

在 Django 中的 ajax POST 期间被禁止(CSRF 令牌丢失或不正确。)