Как сделать AJAX пост запрос в Django
Я хочу опубликовать комментарий с помощью ajax в Django.
У меня есть класс Message, связанный с классом Post, и я использую PostDetailView для отображения содержимого поста и комментариев.
Удалось показать опубликованный комментарий на консоли.
Я получаю ошибку jquery.js:9664 POST http://127.0.0.1:8000/post/39 403 (Forbidden)
это мой код
views.py
class PostDetailView(DetailView):
model = Post
def post(self,request,*args,**kwargs):
if request.method == 'POST':
postid = request.POST.get('postid')
comment = request.POS.get('comment')
# post = Post.objects.get(pk=postid)
user = request.user
Message.objects.create(
user = user,
post_id = postid,
body = comment
)
return JsonResponse({'bool':True})
html (где соответствует разделу комментариев)
{% if request.user.is_authenticated %}
<div>
<form method="POST" action="" id="form_area">
{% csrf_token %}
<input
class="form-control mr-sm-2 comment-text"
type="text"
name="body"
placeholder="Write Your message here..."
/>
<button
class="btn btn-outline-success my-2 my-sm-0 save-comment"
type="submit"
data-post="{{object.id}}"
data-url="{% url 'post-detail' object.id %}"
>
Comment
</button>
</form>
</div>
{% else %}
script.js
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]);
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);
}
function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = "//" + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (
url == origin ||
url.slice(0, origin.length + 1) == origin + "/" ||
url == sr_origin ||
url.slice(0, sr_origin.length + 1) == sr_origin + "/" ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!/^(\/\/|http:|https:).*/.test(url)
);
}
$.ajaxSetup({
// headers: { "X-CSRFToken": getCookie("csrftoken") },
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
// Send the token to same-origin, relative URLs only.
// Send the token only if the method warrants CSRF protection
// Using the CSRFToken value acquired earlier
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
// xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
});
$(document).ready(function () {
$(".save-comment").on("click", function (e) {
e.preventDefault();
let _comment = $(".comment-text").val();
let _postid = $(this).data("post");
let $crf_token = $('[name="csrfmiddlewaretoken"]').attr("value");
$.ajax({
url: $(this).data("url"),
type: "post",
headers: { "X-CSRFToken": $crf_token },
data: {
comment: _comment,
postid: _postid,
csrfmiddlewaretoken: "CSRF-TOKEN-VALUE",
},
dataType: "json",
beforeSend: function () {
$(".save-comment").addClass("disabled").text("saving...");
console.log(_comment);
},
success: function (res) {
$(".save-comment").removeClass("disabled").text("Submit");
},
});
});
});
Как я могу это исправить?
Скорее всего, это связано с токеном csrf. Похоже, что вы получаете токен двумя разными способами. Если вы скопировали код откуда-то, я бы рекомендовал упростить его и следовать рекомендуемому способу согласно docs.
Поскольку вы используете csrf
в форме и предполагаете, что у вас установлено промежуточное ПО, у вас CSRF_USE_SESSIONS
и CSRF_COOKIE_HTTPONLY
должно быть установлено значение False. Поэтому просто передайте переменную, полученную из getcookie
, в запрос headers: {'X-CSRFToken': csrftoken}
и удалите let $crf_token = $('[name="csrfmiddlewaretoken"]').attr("value");
, поскольку кажется, что вы используете ajaxSetup
для установки заголовков с помощью getcookie
, но затем вы перезаписываете их
Если у вас все еще проблемы, я бы предложил закомментировать все эти дополнительные проверки, которые вы делаете, следуйте простому примеру из документации. Затем, если они действительно нужны, начните добавлять проверки одну за другой, пока все не сломается, чтобы можно было отследить источник