ajax页面加载后没有csrf标记

现在我进行了设置,以便在成功登录时登录div淡出并显示一个注销按钮。 我希望能够登出注销并转到我的注销function,只是重定向到原始登录页面,但由于某种原因(仅成功)ajax表单提交突然之后我收到403错误:失败原因:CSRF令牌丢失或不正确。

想知道问题是我没有正确传递CSRF令牌。 我已尝试过页面上的所有内容https://docs.djangoproject.com/en/1.6/ref/contrib/csrf/#ajax

这是我的代码:

urls.py

from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Examples: # url(r'^$', 'reportgenerator.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), url(r'^login/', 'reportgenerator.views.login'), url(r'^logout/', 'reportgenerator.views.logout'), ) 

views.py

 class LoginForm(forms.Form): username = forms.CharField(max_length=200) password = forms.CharField(max_length=200) def login(request): c = {} c.update(csrf(request)) if request.POST: form = LoginForm(request.POST) if form.is_valid(): user = auth.authenticate(username = form.cleaned_data['username'], password = form.cleaned_data['password']) is_success = False if user is not None: auth.login(request, user) is_success = True if request.is_ajax(): if (is_success): return render_to_response('login.html', c, context_instance = RequestContext(request)) return render('was_failure') else: form = LoginForm() c['form'] = form return render(request, 'login.html', c) def logout(request): auth.logout(request) return HttpResponseRedirect('/login/') 

和我的javascript:

 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; } var csrftoken = getCookie('csrftoken'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } function sameOrigin(url) { // test that a given url is a same-origin 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 ie relative. !(/^(\/\/|http:|https:).*/.test(url)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { // Send the token to same-origin, relative URLs only. // Send the token only if the method warrants CSRF protection // Using the CSRFToken value acquired earlier xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); jQuery(function() { var form1 = jQuery("#contactform"); form1.submit(function(e) { $.ajax({ type: "POST", url: form1.attr('action'), data: form1.serializeArray(), success: function() { popup.setAttribute("style","display: none;"); blurback.setAttribute("style", "-webkit-filter: blur(0px)"); $("#welcome").fadeIn("slow"); $("#logoutfade").fadeIn("slow"); }, error: function() { document.getElementById("password").value = ""; } }); e.preventDefault(); }); }); 

Django提供了有关如何执行需要CSRF的Ajax请求的非常详细的信息: https : //docs.djangoproject.com/en/1.6/ref/contrib/csrf/

使用jQuery而不使用jquery cookie addon:

 // using jQuery 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; } var csrftoken = getCookie('csrftoken'); 

使用Jquery和jquery cookie插件:

  var csrftoken = $.cookie('csrftoken'); 

然后:

 function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } function sameOrigin(url) { // test that a given url is a same-origin 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 ie relative. !(/^(\/\/|http:|https:).*/.test(url)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { // Send the token to same-origin, relative URLs only. // Send the token only if the method warrants CSRF protection // Using the CSRFToken value acquired earlier xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); 

编辑(给你答案)更通用的方法:首先确保你启用了中间件:

  'django.middleware.csrf.CsrfViewMiddleware', 

然后在你的JS文件中:

 $(document).on('click', '.some-class', function(){ var $csrftoken = $.cookie('csrftoken'); $.ajax({ type: 'POST', url: /your/url/, crossDomain: false, beforeSend: function(xhr) { xhr.setRequestHeader("X-CSRFToken", $csrftoken); }, success: function(ctx) { console.log(Success!) } }); }); 

为了跟进这一点 – 几天后我想通了。 我遇到此问题的原因是因为在ajax登录之前存在注销按钮。 当用户通过身份validation时,重新生成了crsf令牌,并且该页面的注销按钮附加了旧令牌,因为它是先前生成的。 我在ajax调用之后将其切换为生成登录按钮,一切运行良好。