0

I want to post comment using ajax in Django.

I have Message Class related to Post class, and I using PostDetailView to show content of the post and coments.

I succeeded to show posted comment on the console.

I'm getting error jquery.js:9664 POST http://127.0.0.1:8000/post/39 403 (Forbidden)

this is my code

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(where is corresponds to comment section)

{% 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");
      },
    });
  });
});

All my code

How can I fix this?

1

1 Answer 1

1

This is most likely to do with the csrf token. It seems like you are fetching the token in two different ways. If you copied the code from somewhere I would recommend , simplifying it and follow the recommend way as per the docs.

Since you are using the csrf in the form and assuming you have the middleware set, you should have CSRF_USE_SESSIONS and CSRF_COOKIE_HTTPONLY set to False. So, just pass the variable you get from getcookie into the request headers: {'X-CSRFToken': csrftoken} and remove let $crf_token = $('[name="csrfmiddlewaretoken"]').attr("value"); since it seems like you are using ajaxSetup to set the headers using getcookie but then you overwrite it

If you are still having troubles I would suggest commenting out all those extra checks you're doing, follow the documentation simple example. Then, if you really need them, start adding the checks again one by one until it breaks, so that you can track the source

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.