How to use {% csrf_token %} in javascript
Asked Answered
O

4

7

In my users page, i have in place editing with ajax. And when i click edit, it works fine. But when i submit the form, it don't do anything. When i checked, this is the error:

CSRF verification failed. Request aborted.

So, how do I place {% csrf_token %} in my javascript? Please advice. Thank you.

edit.js:

function bookmark_edit() {
    var item = $(this).parent();
    var url = item.find(".title").attr("href");
    item.load("/save/?ajax&url=" + escape(url), null, function () {
        $("#save-form").submit(bookmark_save);
        });
    return false;
    }

$(document).ready(function () {
    $("ul.bookmarks .edit").click(bookmark_edit);
    });

function bookmark_save() {
    var item = $(this).parent();
    var data = {
        url: item.find("#id_url").val(),
        title: item.find("#id_title").val(),
        tags: item.find("#id_tags").val()
        };
    $.post("/save/?ajax", data, function (result) {
        if (result != "failure") {
        item.before($("li", result).get(0));
        item.remove();
        $("ul.bookmarks .edit").click(bookmark_edit);
        }
        else {
            alert("Failed to validate bookmark before saving.");
        }
        })
        return false;
    }

save_form.html:

<form id = "save-form" method="post" action="/save/">
{% csrf_token %}
    {{form.as_p}}
    <input type="submit" value="Save" />
</form>

user_page.html:

{% extends "base.html" %}
{% block external %}
    <script type = "text/javascript" src="{% static "assets/js/bookmark_edit.js" %}"></script>
{% endblock %}
{% block title %} {{username}} {% endblock %}
{% block head %} Bookmarks for {{username}} {% endblock %}
{% block content %}
    {% include "bookmark_list.html" %}
{% endblock %}

view.py:

@login_required(login_url='/login/')
def bookmark_save_page(request):
    ajax = request.GET.has_key('ajax')
    if request.method == 'POST':
        form = BookmarkSaveForm(request.POST)
        if form.is_valid():
            bookmark = _bookmark_save(request, form)
            if ajax:
                variables = RequestContext(request, {
                    'bookmarks':[bookmark],
                    'show_edit':True,
                    'show_tags':True
                    })
                return render_to_response('bookmark_list.html', variables)
            else:
                return HttpResponseRedirect('/user/%s/' % request.user.username
                    )
        else:
            if ajax:
                return HttpResponseRedirect('failure')
    elif request.GET.has_key('url'):
        url = request.GET['url']
        title = ''
        tags = ''

        try:
            link = Link.objects.get(url=url)
            bookmark = Bookmark.objects.get(
                link=link,
                user = request.user
                )
            title = bookmark.title
            tags = ' '.join(
                tag.name for tag in bookmark.tag_set.all()
                )
        except ObjectDoesNotExist:
            pass
        form = BookmarkSaveForm({
            'url':url,
            'title':title,
            'tags':tags
            })
    else:
        form = BookmarkSaveForm()

    variables = RequestContext(request, {
        'form': form
        })
    if ajax:
        return render_to_response(
            'bookmark_save_form.html',
            variables
            )
    else:
        return render_to_response('bookmark_save.html',variables)
Overzealous answered 20/7, 2013 at 20:23 Comment(0)
D
8

You are not sending the server generated csrf_token for the POST to verify the validity of the data. Hence the error.

As a part of the data part of the request, you need to send the token

csrfmiddlewaretoken: '{{ csrf_token }}' 

Something like this

var data = {
    url: item.find("#id_url").val(),
    title: item.find("#id_title").val(),
    tags: item.find("#id_tags").val(),
    csrfmiddlewaretoken: '{{ csrf_token }}' 
};

Or you could simply do:

var data = $('form').serialize()

if you want to send the whole form as a dictionary

Dioscuri answered 20/7, 2013 at 20:28 Comment(6)
I tried csrfmiddlewaretoken: '{{ csrf_token}}' But it didn't quite helped. And could you plz explain how to send whole as a dictionary?Overzealous
var data = $('form').serialize() would send the whole form as a dictionary.Dioscuri
Thanks! This one worked! Bdw can you suggest me any good books to read for both up to date django version and javascript?Overzealous
I learnt jQuery and Django in depth individually, which helped me tailor the two together to my needs. I would recommend you reading up lots of available blogs online that can help you put the pieces to gether. If you are stuck, StackOverflow is always there to help you.Dioscuri
Does it have, csrf related problems in the book?Overzealous
Yes. Djangoproject does cover it.Dioscuri
V
3

var csrftoken = Cookies.get('csrftoken');

xhr.setRequestHeader("X-CSRFToken", csrftoken);

enter link description here

Viva answered 30/3, 2020 at 3:14 Comment(0)
F
1

This is what I use. Not sure if it's applicable in your situation though.

// sending a csrftoken with every ajax request
function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    crossDomain: false, // obviates need for sameOrigin test
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
        }
    }
});
Falchion answered 20/7, 2013 at 21:20 Comment(0)
F
0
var CSRF_TOKEN = '{{ csrf_token }}';  

Past this is js file

Fucus answered 12/6, 2023 at 12:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.