2016-01-18 9 views
1

Я пробовал следовать руководству this, чтобы получить токен CSRF для отправки с запросом POST, но я всегда получаю ошибку 403.Точка CSRF не работает с запросами AJAX

У меня есть домашняя страница в /, которая содержит ссылку для открытия модального. При щелчке ссылки URL изменяется на /#modal. Когда пользователь вводит адрес электронной почты/пароль и нажимает ссылку на сообщение, он возвращает ошибку 403 с сообщением CSRF token missing or incorrect. Моя базовая страница, которая содержит импорт сценариев и модальный выглядит следующим образом:

<!doctype html> 
{% load staticfiles %} 
<html class="no-js" lang="en"> 
<head> 
    <meta charset="utf-8" /> 
    <meta http-equiv="x-ua-compatible" content="ie=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
    <title>Freelance Student</title> 
    <link rel="stylesheet" href="{% static 'css/normalize.css'%}"> 
    <link rel="stylesheet" href="{% static 'css/style.css'%}" /> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> 
    <link rel="stylesheet" href="{% static 'css/jquery.remodal.css' %}"> 
</head> 
<body> 
    <header class="site-header"> 
    <div class="container"> 
     <div class="site-logo two"> 
     <img src="{% static 'img/logo.png' %}" alt=""> 
     </div> 

     <nav role="navigation" class="nav-collapse"> 
     <ul class="site-nav"> 
     <li><a href="#">Talent Search</a></li> 
     <li><a href="#">Employers</a></li> 
     <li><a href="#">About</a></li> 
     <li><a href="#modal">Login</a></li> 
     <li><a href="#modal2" class="button green">Create a profile</a></li> 
     </ul> 
    </nav> 
    <div class="remodal" data-remodal-id="modal"> 
     <div class="login"> 
     <div class="favicon"><img src="{% static 'img/favicon.png' %}" /></div> 
     <div class="login-iner"> 
      <form id="login" method="post" action="#"> 
       {% csrf_token %} 
       {{login_form.as_p}} 
       <a id="post" href="">post</a> 
      <!--<input type="submit" value="Login" />--> 
      </form> 
     </div> 
     <p>Forgot username/password? <span class="lspan"><a href="#">Click here</a></span></p> 
     </div> 
    </div> 
    <div class="remodal" data-remodal-id="modal2"> 
     <div class="logot"> 
     <div class="favicon"><img src="images/favicon.png" /></div> 
     <h1>Complete the form to build your profile</h1> 
     <div class="logot-iner"> 
      <form> 
      <p> 
      My name is &nbsp;&nbsp; 
      <input type="text" placeholder="first name" /> 
      &nbsp;&nbsp; 
      <input type="text" placeholder="last name" /> 
      and I am a &nbsp;&nbsp;<span class="type"> 
      <input type="text" placeholder="student type" /> 
      </span> &nbsp;&nbsp; Student 
      <br /> 
      <br /> 
      I am completing a &nbsp;&nbsp; <span class="type"> 
      <input type="text" placeholder="degree type" /> 
      </span> &nbsp;&nbsp; degree at<br /> 
      <span class="type1"> 
      <input type="text" placeholder="uni/college" /> 
      </span> 
      <br /> 
      <br /> 
      I study/studied &nbsp;&nbsp; <span class="type2"> 
      <input type="text" placeholder="degree subject" /> 
      </span> &nbsp;&nbsp;and I 
      am currently in my &nbsp;&nbsp;<span class="type"> 
      <input type="text" placeholder="select year" /> 
      </span> &nbsp;&nbsp; year. 
      <br /> 
      <br /> 
      DOB: &nbsp;&nbsp; <span class="type3"><input type="text" placeholder="DD" /></span>&nbsp;&nbsp; 
      <span class="type3"><input type="text" placeholder="MM" /></span> &nbsp;&nbsp; 
       <span class="type3"><input type="text" placeholder="YYYY" /></span> &nbsp;&nbsp; 
      <br /> 
      <br /> 
      My primary skill area is &nbsp;&nbsp; <span class="type"> 
      <input type="text" placeholder="skill area" /> 
      </span> &nbsp;&nbsp;<br /> 
      <br /> 
      <span class="lspan1">You must be at least 18 years of age to join</span><br /> 
      <br /> 
      <input type="submit" value="Sign up" /> 
      </p> 
      </form> 
     </div> 
     </div> 
    </div> 
    </div> 
    <!-- /.container --> 
</header> 
<!-- /.site-header --> 
    {% block content %} {% endblock %} 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
    <script src="{% static 'js/vendor/responsive-nav.min.js' %}"></script> 
    <script src="{% static 'js/main.js' %}"></script> 
    <script src="{% static 'js/base.js' %}"></script> 
    <script src="{% static 'js/vendor/jquery.min.js' %}"></script> 
    <script src="{% static 'js/jquery.remodal.js' %}"></script> 

</body> 
</html> 

и соответствующий файл JavaScript выглядит следующим образом:

$(document).ready(function(){ 

    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; 
    } 

    $.ajaxSetup({ 
     beforeSend: function(xhr, settings) { 
      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')); 
      } 
     } 
    }); 


    $('a#post').on('click', function(e) { 

     e.preventDefault(); 

     $.ajax({ 
      type : 'POST', 
      url : window.location.href, 
      dataType: 'json', 
      data: {'foo': 'bar'}, 
      beforeSend: function(xhr, settings) { 
       console.log("Before Send"); 
       $.ajaxSettings.beforeSend(xhr, settings); 
      }, 
      success: function(data){ 
       console.log(data); 
      }, 
     }); 
    }); 
}); 

Я не понимаю, что я не хватает? Я включил {% csrf_token %} и JavaScript печатает Before Send на консоль.

+0

btw, вы включаете jquery два раза. Это может вызвать некоторые проблемы. – Lucas03

ответ

1

Вы написали свою функцию beforeSend только для отправки CSRF на локальные URL-адреса, то есть те, которые не начинаются с http или https. Однако вы создали URL-адрес, который посылает ваш Ajax, просто получив window.location.href, который делает, включая эту строку. Вам нужно либо использовать относительный URL-адрес, либо изменить логику в beforeSend.

Обратите также внимание, что вы не должны называть этот метод напрямую; вся точка вызова ajaxSetup заключается в том, что он делает это автоматически. Удалите часть beforeSend вашего фактического звонка .ajax.

Смежные вопросы