Django rest框架ajax表单提交错误403(禁止)



当我试图提交与DRF API一起使用的ajaxized表单时,我会进入浏览器控制台!

POSThttp://localhost:8000/api/texts/403(禁止(

这是我的html文件:

<form id="text-form" method="POST" action="">

<input type="text" name="title" placeholder="Title" class="form-control mb-3 pb-2"
maxlength="200" required id="title">
<input type="date" name="deadline" placeholder="Deadline" autocomplete="off"
class="form-control mb-3" id="myflatpickr">                                         

<textarea name="requirements" cols="40" rows="4"
placeholder="requirements"
class="form-control col mt-3" maxlength="200" required id="requirements"></textarea>
<textarea name="document" cols="40" rows="10"
placeholder="document"
id="editor" class="form-control" required></textarea>
<button type="submit">Submit</button>
</form>

这是我的javascript文件

$("#text-form").submit(function (event) {
event.preventDefault();
$textData = $("#text-form").serialize()
$.ajax({
url: "http://localhost:8000/api/texts/",
method: "POST",
data: $textData,
success: function() {
console.log($textData)
},
error: function() {
console.log("there is an error")
}
})
});

在serializers.py:中


from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from rest_framework import serializers
from .models import *

class TextSerializer(serializers.ModelSerializer):
author = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
class Meta:
model = Text
fields = '__all__'

在我的views.py文件中:


class ApiTextList(generics.ListCreateAPIView):
queryset = Text.objects.all()
serializer_class = TextSerializer
permission_classes = [
permissions.AllowAny
]

class ApiTextDetail(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
http_method_names = ['get', 'head']
queryset = Text.objects.all()
serializer_class = TextSerializer
permission_classes = [
permissions.AllowAny
]
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)

在urls.py 中

from django.urls import path
from . import views

urlpatterns = [
path('api/texts/', views.ApiTextList.as_view()),
path('api/texts/<int:pk>/', views.ApiTextDetail.as_view()),


]

注意:当我尝试从drf在"中提供的界面添加文本时;localhost:8000/api/texts";我正常添加

既然您告诉了我们详细信息字段的内容,那么应该更容易解决您的问题。

Django文档建议您从cookie中获取CSRF令牌。

它甚至为您提供了以下功能:

function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// 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;
}

然后,您可以通过添加以下两行来轻松地调整自己的代码:

$("#text-form").submit(function (event) {
event.preventDefault();
const csrftoken = getCookie('csrftoken'); // HERE: get the token 
$textData = $("#text-form").serialize()
$.ajax({
url: "http://localhost:8000/api/texts/",
method: "POST",
data: $textData,
headers:{"X-CSRFToken": csrftoken }, // HERE: add it to the request header
success: function() {
console.log($textData)
},
error: function() {
console.log("there is an error")
}
})
});

如果不起作用,请检查您是否正确使用了会话身份验证。

为了回答您的其他询问,您的注册视图在没有CSRF令牌的情况下工作是正常的:在DRF中,只有需要验证的视图才需要它。

您收到错误403,这意味着服务器理解请求但拒绝授权。您需要在发送ajax请求时添加授权令牌。

您可以使用此授权页面上的令牌。

<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>

然后,您必须将令牌添加到您的ajax请求中。

$.ajax({
url: "http://localhost:8000/api/texts/",
method: "POST",
data: $textData,
csrfmiddlewaretoken: window.CSRF_TOKEN,
success: function() {
console.log($textData)
},
error: function() {
console.log("there is an error")
}
})

试试这个,对于Forbidden 403

$.ajax({
url: "http://localhost:8000/api/texts/",
method: "POST",
data: $textData,
contentType: "application/json;charset=utf-8",
dataType: "json",
headers: {"X-CSRFToken": "{{ csrf_token }}"},
success: function() {
console.log($textData)
},
error: function() {
console.log("there is an error")
}
})

最新更新