[英]Django rest framework ajax form submit error 403 (forbidden)
當我嘗試提交與 DRF API 一起使用的 ajaxified 表單時,我進入了瀏覽器控制台!
POST http://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")
}
})
});
如果這不起作用,請檢查您是否正確使用Session Authentication 。
為了回答您的其他詢問,您的注冊視圖在沒有 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")
}
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.