详细信息:"CSRF Failed: CSRF token missing or incorrect."
detail: "CSRF Failed: CSRF token missing or incorrect."
我在 restaurant_detail.html 中的脚本标签内使用了 window.CSRF_TOKEN = "{{ csrf_token }}" ,其中呈现了我用于发布评论的反应页面。不过,我收到一个错误。在我的 onSubmit 函数中,我安慰检查 csrf 令牌是否通过,是的。
我用于发布评论的 axios 代码是
onSubmit(props){
console.log('csrf',CSRF_TOKEN);
axios({
method:'POST',
url:'/api/review/create/',
headers:{
'X-CSRF-Token':CSRF_TOKEN,
//'Access-Control-Allow-Origin':'*',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
data:{
review:props.review
}
})
.then(response => {
console.log('success');
})
.catch(error => {
throw("Error: ",error);
});
}
api/Views.py
class ReviewCreateAPIView(CreateAPIView):
queryset = Review.objects.all()
# permisssion_classes = [IsAuthenticated]
def get_serializer_class(self):
model_type = self.request.GET.get('type')
slug = self.request.GET.get('slug')
parent_id = self.request.GET.get('parent_id')
return create_review_serializer(model_type=model_type, slug=slug, parent_id=parent_id, reviewer=self.request.user)
serializers.py
def create_review_serializer(model_type='restaurant',slug=None, parent_id=None, reviewer=None):
class ReviewCreateSerializer(ModelSerializer):
class Meta:
model = Review
fields = ('id','review','created',)
def __init__(self, *args, **kwargs):
self.model_type = model_type
self.slug = slug
self.parent_obj = None
if parent_id:
parent_qs = Review.objects.filter(id=parent_id)
if parent_qs.exists() and parent_qs.count() == 1:
self.parent_obj = parent_qs.first()
return super(ReviewCreateSerializer, self).__init__(*args, **kwargs)
def validate(self, data):
model_type = self.model_type
model_qs = ContentType.objects.filter(model=model_type)
if not model_qs.exists() or model_qs.count() != 1:
raise ValidationError('This is not a valid content type')
SomeModel = model_qs.first().model_class()
obj_qs = SomeModel.objects.filter(slug=self.slug) # Restaurant.objects.filter(slug=self.slug)
if not obj_qs.exists() or obj_qs.count() != 1:
raise ValidationError('This is not a slug for this content type')
return data
def create(self, validated_data):
review = validated_data.get('review')
print('review',review)
if reviewer:
main_reviewer = reviewer
else:
main_reviewer = User.objects.all().first()
model_type = self.model_type
slug = self.slug
parent_obj = self.parent_obj
review = Review.objects.create_for_model_type(model_type, slug, review, main_reviewer, parent_obj=parent_obj)
return review
return ReviewCreateSerializer
urls.py
url(r'^create/$', ReviewCreateAPIView.as_view(), name="reviewcreateapiview"),
restaurant_detail.html
<div id="app"></div>
<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
我该如何解决这个问题?
我对axios不熟悉,但是我解决了一个类似的问题,使用blow代码JQuery:
$.ajaxSetup({
data : {
csrfmiddlewaretoken : '{{ csrf_token }}'
},
});
您必须使用 cookie 值在 ajax 调用中设置 header。
$.ajaxSetup({
beforeSend: function(xhr, settings) {
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;
}
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'));
}
}
});
你犯了一个简单的错误。有错别字。替换
'X-CSRF-Token'
到
'X-CSRFToken'
如果您的代码正确,那么它应该post您的数据。
我在 restaurant_detail.html 中的脚本标签内使用了 window.CSRF_TOKEN = "{{ csrf_token }}" ,其中呈现了我用于发布评论的反应页面。不过,我收到一个错误。在我的 onSubmit 函数中,我安慰检查 csrf 令牌是否通过,是的。
我用于发布评论的 axios 代码是
onSubmit(props){
console.log('csrf',CSRF_TOKEN);
axios({
method:'POST',
url:'/api/review/create/',
headers:{
'X-CSRF-Token':CSRF_TOKEN,
//'Access-Control-Allow-Origin':'*',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
data:{
review:props.review
}
})
.then(response => {
console.log('success');
})
.catch(error => {
throw("Error: ",error);
});
}
api/Views.py
class ReviewCreateAPIView(CreateAPIView):
queryset = Review.objects.all()
# permisssion_classes = [IsAuthenticated]
def get_serializer_class(self):
model_type = self.request.GET.get('type')
slug = self.request.GET.get('slug')
parent_id = self.request.GET.get('parent_id')
return create_review_serializer(model_type=model_type, slug=slug, parent_id=parent_id, reviewer=self.request.user)
serializers.py
def create_review_serializer(model_type='restaurant',slug=None, parent_id=None, reviewer=None):
class ReviewCreateSerializer(ModelSerializer):
class Meta:
model = Review
fields = ('id','review','created',)
def __init__(self, *args, **kwargs):
self.model_type = model_type
self.slug = slug
self.parent_obj = None
if parent_id:
parent_qs = Review.objects.filter(id=parent_id)
if parent_qs.exists() and parent_qs.count() == 1:
self.parent_obj = parent_qs.first()
return super(ReviewCreateSerializer, self).__init__(*args, **kwargs)
def validate(self, data):
model_type = self.model_type
model_qs = ContentType.objects.filter(model=model_type)
if not model_qs.exists() or model_qs.count() != 1:
raise ValidationError('This is not a valid content type')
SomeModel = model_qs.first().model_class()
obj_qs = SomeModel.objects.filter(slug=self.slug) # Restaurant.objects.filter(slug=self.slug)
if not obj_qs.exists() or obj_qs.count() != 1:
raise ValidationError('This is not a slug for this content type')
return data
def create(self, validated_data):
review = validated_data.get('review')
print('review',review)
if reviewer:
main_reviewer = reviewer
else:
main_reviewer = User.objects.all().first()
model_type = self.model_type
slug = self.slug
parent_obj = self.parent_obj
review = Review.objects.create_for_model_type(model_type, slug, review, main_reviewer, parent_obj=parent_obj)
return review
return ReviewCreateSerializer
urls.py
url(r'^create/$', ReviewCreateAPIView.as_view(), name="reviewcreateapiview"),
restaurant_detail.html
<div id="app"></div>
<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
我该如何解决这个问题?
我对axios不熟悉,但是我解决了一个类似的问题,使用blow代码JQuery:
$.ajaxSetup({
data : {
csrfmiddlewaretoken : '{{ csrf_token }}'
},
});
您必须使用 cookie 值在 ajax 调用中设置 header。
$.ajaxSetup({
beforeSend: function(xhr, settings) {
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;
}
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'));
}
}
});
你犯了一个简单的错误。有错别字。替换
'X-CSRF-Token'
到
'X-CSRFToken'
如果您的代码正确,那么它应该post您的数据。