我在我的學習專案 django rest 框架中使用。當我嘗試使用 POST 方法保存時,出現錯誤 403 Forbidden(CSRF 令牌丟失或不正確。這是我的代碼 html
<form id = "product_form" method = "post">
{% csrf_token %}
<input type = "hidden" name = "id" id = "id">
<p>Назвние:<input name = "name" id = "name"></p>
<p><input type = "reset" value = "Oчистить"></p>
<input type = "submit" value = "Сохранить">
</form>
這是我的代碼js:
let productUpdater = new XMLHttpRequest();
productUpdater.addEventListener('readystatechange', () => {
if (productUpdater.readyState == 4) {
if ((productUpdater.status == 200) || (productUpdater.status == 201)) {
listLoad();
name.form.reset();
id.value = '';
} else {
window.alert(productUpdater.statusText)
}
}
}
);
name.form.addEventListener('submit', (evt) => {
evt.preventDefault();
// let vid = id.value, url, method;
let vid = id.value;
if (vid) {
url = 'http://127.0.0.1:8000/books/api_category/' vid '/';
method = 'PUT';
} else {
url = 'http://127.0.0.1:8000/books/api_category/';
method = 'POST';
}
let data = JSON.stringify({id: vid,nameCategory: name.value});
productUpdater.open(method, url, true);
productUpdater.setRequestHeader('Content-Type', 'application/json');
productUpdater.send(data);
})
這是我的views.py:
@api_view(['GET', 'POST'])
def api_products(request):
if request.method == 'GET':
productsAll = CategoryMaskarad.objects.all()
serializer = CategorySerializer(productsAll, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = CategorySerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
def api_rubric_detail(request, pk):
product = CategoryMaskarad.objects.get(pk=pk)
if request.method == 'GET':
serializer = CategorySerializer(product)
return Response(serializer.data)
elif request.method == 'PUT' or request.method == 'PATCH':
serializer = CategorySerializer(product, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
product.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
這是我的 urls.py:
path('api_category/<int:pk>/', api_rubric_detail),
path('api_products/', api_products),
path('api/drf-auth/', include('rest_framework.urls'))
我添加了最后一個路徑并登錄。在api界面中可以使用post方法添加到api中,但是在我的html中的js的幫助下我無法添加資料。請幫幫我
uj5u.com熱心網友回復:
將表單中的資料傳遞給 django rest 框架時,您不會在表單之前添加 csrf_token 標記,而是在端點上發送 api post 時將其作為標頭傳遞。在后面加上這一行
嘗試將此函式添加到您的代碼中以獲取 csrftoken 的值
let 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 = cookies[i].trim();
if(cookie.substring(0, name.length 1)===(name '=')){
cookieValue = decodeURIComponent(cookie.substring(name.length 1));
break;
}
}
}
return cookieValue;
}
然后更改您在 x-csrf-token 中使用的值并使其
productUpdater.setRequestHeader('Content-Type', 'application/json');
productUpdater.setRequestHeader('X-CSRF-Token', getCookie("csrftoken"));
uj5u.com熱心網友回復:
我有這個選項。他正在作業。我添加到 js 檔案中:
name.form.addEventListener('submit', (evt) => {
evt.preventDefault();
// let vid = id.value, url, method;
let vid = id.value, url, method;
if (vid) {
url = 'http://127.0.0.1:8000/books/api_category/' vid '/';
method = 'PUT';
} else {
url = 'http://127.0.0.1:8000/books/api_category/';
method = 'POST';
}
let data = JSON.stringify({id: vid, nameCategory: name.value});
productUpdater.open(method, url, true);
productUpdater.setRequestHeader('Content-Type', 'application/json');
productUpdater.setRequestHeader('X-CSRFToken', csrftoken);
productUpdater.send(data);
})
我添加到 html 檔案中:
<script>
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
</script>
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/449350.html
標籤:javascript Python django 邮政 django-rest-framework
上一篇:將串列分配給通用串列
下一篇:Tabview滾動行為
