Jquery 和 Django CSRF 令牌
我有两个HTML页面。
一个是父页面,另一个是子页面。子页面上有一个提交按钮,点击这个按钮会在父页面上运行代码,发送一个Ajax消息。
我使用$.load()方法加载子页面,然后当按钮被点击时,它会运行一个$.ajax .POST方法。这个POST方法只会把一个JSON字符串传递给Python代码。
在除了IE以外的任何浏览器上,这个操作都很顺利。但是在IE中运行这段代码时,我遇到了关于CSRF令牌的Python/Django错误。
我觉得问题可能是因为子页面实际上只是当前页面的刷新,而服务器端的代码正在运行。
有没有人知道我该如何解决这个问题?
谢谢!
3 个回答
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交互的方法。
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);
});
}
44
你没有在POST请求中传递csrf令牌。试试我在data中做的事情。也就是说,获取csrf令牌(或者用你自己的方法),然后把它放在你的参数里。
$.ajax({
url : url,
type: "POST",
data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value},
dataType : "json",
success: function( data ){
// do something
}
});