Jquery和Django的CSRF令牌

30

我有两个 HTML 页面,一个父页面和一个子页面。子页面包含一个提交按钮,单击该按钮会在父页面上运行代码以提交 Ajax 消息。

我使用 $.load() 方法加载子页面,然后当按钮被单击时,它会运行 $.ajax .POST 方法。这个 POST 方法只传递一个 JSON 字符串给 Python 代码。

在除 IE 外的任何浏览器上都可以正常工作。但是在 IE 中运行此代码时,会出现有关 CSRF 令牌的 Python/Django 错误。

我认为原因是子页面只是当前页面本身的刷新,而服务器端代码正在运行。

有谁知道我应该如何让它正常工作呢?

干杯,

3个回答

43

您没有使用POST方法传递csrf令牌。尝试像data中所做的那样。即获取csrf令牌(或使用您自己的方法)并将其作为参数传递。

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

4
这种方法可以,但如果你要进行多个ajax请求,把CSRF令牌作为标头传递可能更方便。有关更多信息,请参阅django文档 - Alasdair
13
我觉得 data: {..., 'csrfmiddlewaretoken': '{{ csrf_token }}'}, ... 更直接明了。 - Tuttle
或者在 .html 模板中使用以下代码: <script> var django_csrf_token = '{{ csrf_token }}'; </script>,以便从静态的 .js 中使用。 - Eugene Gr. Philippov

13

如果您正在发送POST请求主体,将CSRF令牌作为请求标头添加可能更容易。 我发现这种方法更容易阅读,因为它不会在请求主体中混杂令牌。 大多数AJAX请求将根据Django文档的建议将CSRF令牌作为标头发送。

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

9

以下是有关CSRF和AJAX的文档:

CSRF令牌也存在于DOM中,但仅当在模板中使用csrf_token进行显式包含时才存在。 cookie包含规范令牌; CsrfViewMiddleware将优先使用cookie而不是DOM中的令牌。无论如何,如果在DOM中存在令牌,则保证会有cookie,因此您应该使用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');

或者可以使用任何其他与cookie交互的方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接