2011-12-23 4 views
18

У меня есть 2 html Страницы.JQuery и Jango CSRF Token

Родительская страница и страница ребенка. Страница «Дети» содержит кнопку «Отправить», которая запускает код на родительской странице для отправки сообщения Ajax.

Загружаю дочернюю страницу с помощью метода $ .load(), а затем при нажатии кнопки запускается метод $ .ajax POST. Этот метод post передает только код JSON в код Python.

Когда я делаю это в любом браузере, кроме IE, он отлично работает. Однако, когда я запускаю этот код в IE. Я получаю ошибки Python/Django о токенах CSRF.

I Think Причина в том, что дочерняя страница является только обновлением текущей страницы с запущенным кодом сервера.

Кто-нибудь знает, как я должен работать над этим.

Cheers,

ответ

29

Вы не передавая маркер CSRF с POST. Попробуйте сделать то, что я сделал в данные. То есть, чтобы получить токен csrf (или ваш собственный метод) и передать его в ваших аргументах.

$.ajax({ 
    url : url, 
    type: "POST", 
    data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value}, 
    dataType : "json", 
    success: function(data){ 
     // do something 
    } 
}); 
+0

Работало как очарование. Большое спасибо :-) – TheMonkeyMan

+4

Этот подход прекрасен, но если вы делаете много запросов ajax, вам может быть удобнее передавать токен CSRF в качестве заголовка. Для получения дополнительной информации см. [Django docs] (https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax). – Alasdair

+7

Я нахожу 'данные: {..., 'csrfmiddlewaretoken': '{{csrf_token}}'}, ... более простым. – Tuttle

5

Из docs на CSRF и AJAX:

токен CSRF также присутствует в DOM, но только если явно включена с помощью csrf_token в шаблоне. Файл cookie содержит канонический токен; CsrfViewMiddleware предпочтет cookie для токена в DOM. Несмотря на это, у вас гарантированно будет файл cookie, если токен присутствует в DOM, поэтому вы должны использовать cookie!

Пример(также из документации)

// 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'); 

Или любой другой способ взаимодействия с печеньем можно было бы использовать.

6

Если вы отправляете тело запроса POST, возможно, проще добавить токен csrf в качестве заголовка запроса. Я считаю, что этот подход легче читать, поскольку он не загромождает тело запроса с помощью токена. Большинство запросов AJAX отправят токен csrf в виде заголовка, как это было предложено в документации Django.

function startTest(testId) { 
    var payload = JSON.stringify({ 
    test_id : testId 
    }); 
    $.ajax({ 
    url: "/test-service/", 
    method: "POST", 
    headers: {'X-CSRFToken': '{{ csrf_token }}'}, 
    data: payload, 
    dataType: "json" 
    }).done(function(response) { 
    console.log(response.id + " " + response.name); 
    }).fail(function (error) { 
     console.log(error); 
    }); 
}