How to use {% csrf_token %} in javascript

14,047

Solution 1

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

Solution 2

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'));
        }
    }
});
Share:
14,047
Karl
Author by

Karl

Updated on June 17, 2022

Comments

  • Karl
    Karl almost 2 years

    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)
    
  • Karl
    Karl almost 11 years
    I tried csrfmiddlewaretoken: '{{ csrf_token}}' But it didn't quite helped. And could you plz explain how to send whole as a dictionary?
  • karthikr
    karthikr almost 11 years
    var data = $('form').serialize() would send the whole form as a dictionary.
  • Karl
    Karl almost 11 years
    Thanks! This one worked! Bdw can you suggest me any good books to read for both up to date django version and javascript?
  • karthikr
    karthikr almost 11 years
    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.
  • Karl
    Karl almost 11 years
    Does it have, csrf related problems in the book?
  • karthikr
    karthikr almost 11 years
    Yes. Djangoproject does cover it.