Sumra
Sumra

Reputation: 29

CSRF token missing or incorrect - displaying dynamic html content with django and js

I'm trying to load data with ajax using this tutorial. I'm using Django as a framework for my project and unfortunately the data does not load propely, instead I get a following error message: "CSRF token missing or incorrect". I assume I need to somehow insert the csrf token into the request but not quite sure how to achieve this. Below is the code.

views.py

def ChapterListPL(request):
    chapter_pl = ChapterPL.objects.filter(status=1).order_by('issue')
    context = {
        'chapter_pl': chapter_pl,
        }
    return render(request, 'comics/chapters_pl.html', context)

html file

<div id="container"></div>
<input type="button" value="AJAX Load" onclick="aload();"/>

<script>
    function aload() {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "{% url 'chapter_pl' %}");
        xhr.onload = function () {
            document.getElementById("container").innerHTML = this.response;
        };
        xhr.send();
    }
</script>

Upvotes: 0

Views: 988

Answers (2)

Lucas Weyne
Lucas Weyne

Reputation: 1152

You must include the CSRF token in your HTML, read the token from the DOM with JavaScript and send on request through X-CSRFToken HTTP Header (as specified by the CSRF_HEADER_NAME setting):

{% csrf_token %}
<script>
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
</script>  



<div id="container"></div>
<input type="button" value="AJAX Load" onclick="aload();"/>

<script>
    function aload() {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "{% url 'chapter_pl' %}");
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
        xhr.onload = function () {
            document.getElementById("container").innerHTML = this.response;
        };
        xhr.send();
    }
</script>

See the docs for using AJAX with CSRF Tokens

Upvotes: 1

Clement Murphy
Clement Murphy

Reputation: 36

All Django forms are CSRF protected by default, and your HTML input element counts as a form. Either include the {% csrf_token %} tag in your HTML or include the @csrf_exempt decorator in your views.py file. See more docs here:

Django CSRF tokens

Upvotes: 1

Related Questions