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)

4 Answers 4

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

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

6 Comments

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

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

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

enter link description here

Comments

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'));
        }
    }
});

Comments

0
var CSRF_TOKEN = '{{ csrf_token }}';  

Past this is js file

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.