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 禁止错误