我正在使用REST API编写网站。我在后端使用django和活塞(也使用corsheaders.middleware.CorsMiddleware和CORS_ORIGIN_ALLOW_ALL = True)。我使用backbone.js作为前端。我正在从客户端发送POST请求并收到错误:
CSRF verification failed. Request aborted.
我已经google了很多,并且所有解决方案都提供了类似“使用自动添加RequestContext的渲染快捷方式”之类的内容。但我没有看法,将从前端请求表格,不应该知道后端如何工作。这是我的scipt的代码
Question = Backbone.Model.extend({
urlRoot: 'http://example.com/api/questions',
defaults: {
id: null,
title: '',
text: ''
},
initialize: function() {
//alert(this.title);
}
});
var question2 = new Question;
var questionDetails = {title: 'test title', text: 'test text'};
question2.save(questionDetails, {
success: function(question) {
alert(question.toJSON());
}
});
答案 0 :(得分:1)
django文档有关于如何设置jquery以通过ajax发送csrf令牌的说明。
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
您应该确保模板标记{% csrf_token %}
在您的前端呈现内容。这样您就知道正在创建令牌并将其传递给前端。如果您按照上述文档中的说明进行操作,则应始终使用ajax请求发送csrf令牌。这就是我的一个网站的javascript(假设你使用的是jQuery)。
// Set up Django CSRF Token Protection
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));
}
$.ajaxSetup({
crossDomain: false, // obviates need for sameOrigin test
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
另外,请确保您的MIDDLEWARE_CLASSES设置中有'django.middleware.csrf.CsrfViewMiddleware'
。
答案 1 :(得分:0)
听起来你需要通过保存请求传递CSRF令牌。
一种解决方案是将CSRF令牌传递回请求它的模型,然后覆盖模型的保存方法,确保模型将CSRF令牌传回给它。
Question = Backbone.Model.extend({
urlRoot: 'http://example.com/api/questions',
defaults: {
csrf: null,
id: null,
title: '',
text: ''
},
initialize: function() {
//alert(this.title);
}
save: function( data, options ){
data = $.extend( true, {
csrf: this.get( 'csrf' )
}, data );
options = _.extend( options, {
error: onError,
success: onSuccess
} );
// Call super method.
Backbone.Model.prototype.save.apply( this, [ data, options ] );
}
});