我一直从Django得到403错误。
我设置我的settings.py以使用CSRF保护,并在我的模板中使用了csrf_token标记。
这是我在HTML标题后面包含的JS文件:http://bpaste.net/show/87791/
使用Firebug我可以检查CSRF cookie是否存在。稍后在页面上,用户单击触发此代码的按钮:
myFunction: function() {
$.ajax({
type: 'POST',
url: window.localtion.href + 'myajaxview',
async: false
});
}
我正在使用从TemplateView继承的简单类视图来显示此页面。 'myajaxview'继承自View和JSON Mixin。但是,由于django无法验证CSRF令牌,因此永远不会执行其代码。
在我看来,ajax不会发送带有POST标头的令牌。或者我错过了什么?
编辑:我在调用$ .ajax()POST函数之前移动了$ .ajaxSetup调用,但它运行正常。我试图把它移到其他地方但它失败了。我认为问题与Ajax的关系比Django更多。 所以,我的问题仍然存在,我不想在每次$ .ajax调用之前调用$ .ajaxSetup,我不认为这是事情的完成方式,我不想重复自己。所以这只是一种解决方法,我要求解决方案。
答案 0 :(得分:3)
myFunction: function() {
$.ajax({
type: 'POST',
data: {
'csrfmiddlewaretoken': '{{csrf_token}}'
},
url: '/myajaxview/',
async: false
});
}
答案 1 :(得分:2)
这是我认为您正在寻找的代码片段
var csrfToken = $('input[name="csrfmiddlewaretoken"]').val();
$.ajax({
url: 'blah.com/',
//snipped for brevity
csrfmiddlewaretoken: csrfToken,
success: function(data){ doStuff(); }
});
这是我使用的,以便能够对django应用程序进行jquery ajax调用。 希望它有效!
答案 2 :(得分:1)
感谢您的帮助。答案非常讨厌,我通过一个简单的例子开始测试ajaxSetup + ajax,然后我添加了更多的复杂性以匹配我的原始代码。
这是因为jquery-tools。当我开始使用bootstrap-twitter时,我看到他们建议将javascript包含在页面末尾。所以我也把jquery-tools.js包含在那里。我几乎不知道在这个脚本文件中调用了$ .ajaxSetup,它已经覆盖了我自己。
解决方案是将jquery工具包含在顶层。但是在这一点上,我不确定它会与我的代码冲突多少。因为我需要为每个ajax请求提供ajaxSetup。
我花了一天时间才发现,我在#jquery和#django上,很多人都试图找出解决方案。如果你得到一个你无法分享的复杂代码库,你想要解决的问题是我的建议:尝试让最简单的例子工作并改变它,直到它与你的失败设置相匹配。它将节省每个人的时间,尤其是你自己的时间。
答案 3 :(得分:0)
首先,您是否检查过CSRF代码是否实际发送到服务器?如果是,服务器是否期望散列位于post值或标题中?现在您设置请求标头。 如果两者都无法解决问题,请验证服务器是否知道正确的哈希值。当客户端发送正确的散列并且服务器将NULL作为散列时,则验证将失败。
答案 4 :(得分:0)
我通过在DOM准备就绪时计算令牌的值来解决问题,并且AJAX重新加载。
javascript代码使用reload_ajax()函数来处理令牌,以及在初始页面加载和后续AJAX调用时需要刷新的任何其他内容。
<script type="text/javascript">
function reload_ajax() {
// Useful on initial page load, and after calling AJAX.
$("input#token").val("{{ csrf_token }}");
}
$(document).ready(function() {
$("form#stats").unbind("submit"); // Prevents calling document-ready multiple times
$("form#stats").submit(function(event) {
event.preventDefault();
$.ajax({
type:"POST",
url: $(this).attr("action"),
data: $(this).serialize(), // Serialize the form
dataType: "json",
success: function(response){
$("#stats_ajax").html(response.html); // Object to refresh after AJAX
reload_ajax();
}
});
return false;
});
reload_ajax();
});
</script>
我使用了两个HTML文件, 在main.html中,我有上面的javascript代码,以及以下内容:
<div id="stats_ajax">
{% include "stats_ajax.html" %}
</div>
在stats_ajax.html中,我有实际的表格(以及我需要刷新的其他内容)
<form id="stats" action="/main/" method="post">
<!-- The value will be inserted when the DOM reloads. -->
<input id="token" type="hidden" name="csrfmiddlewaretoken" value="" />
<!-- Other input elements -->
<button type="submit">Submit</button>
</form>
在我的views.py文件中,
# Not all imports may be needed for this example
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.template.loader import render_to_string
import json
def main(request):
# This request should only be posting AJAX
if request.is_ajax():
data = {}
data["message"] = "Awesome"
# This is the template to load on the DOM object to update
html = render_to_string("stats_ajax.html", data)
res = {"html": html}
return HttpResponse(json.dumps(res), mimetype='application/json')
# Handle GET to this view
return redirect("/main")
最后,我的urls.py有
# Replace "application_name" with your own value
url(r'^main', 'application_name.views.main'),