0

My jQuery function looks like

$("body").on("submit","form",function(e){
        // do not submit the form
        e.preventDefault();

        // handle everything yourself
        var $form = $(this);
        var title = $form.closest('.video-detail').find('.title').text();
        var entryTitle = $form.find('.input-small').val();
        console.debug(title);
        console.debug(entryTitle);

        // send the data to the server using .ajax() or .post()
        $.ajax({
            type: 'POST',
            url: 'addVideo',
            data: {video_title: title},
        }).done(function(){
            alert('done');
        });
    });

Then my urls.py looks like

urlpatterns = patterns('',
    url(r'^$', home),
    url(r'^done$', done, name='done'),
    url(r'', include('social_auth.urls')),
    url(r'^addVideo$', addVideo)
)

My views.py looks like

@login_required()
@transaction.commit_on_success
def addVideo(request):
    logging.info('add Video request - ' + str(request))
    pass

When I run my web app, I debug the console using firebug I see the error

my.js (line 96)
POST http://myaap.in/addVideo

403 FORBIDDEN    43ms

and then when I drill it further in response, I see

<div id="summary">
  <h1>Forbidden <span>(403)</span></h1>
  <p>CSRF verification failed. Request aborted.</p>

</div>

<div id="info">
  <h2>Help</h2>

    <p>Reason given for failure:</p>
    <pre>
    CSRF cookie not set.
    </pre>


  <p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when
  <a
  href='http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ref-contrib-csrf'>Django's
  CSRF mechanism</a> has not been used correctly.  For POST forms, you need to
  ensure:</p>

  <ul>
    <li>Your browser is accepting cookies.</li>

    <li>The view function uses <a
    href='http://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext'><code>RequestContext</code></a>
    for the template, instead of <code>Context</code>.</li>

    <li>In the template, there is a <code>{% csrf_token
    %}</code> template tag inside each POST form that
    targets an internal URL.</li>

    <li>If you are not using <code>CsrfViewMiddleware</code>, then you must use
    <code>csrf_protect</code> on any views that use the <code>csrf_token</code>
    template tag, as well as those that accept the POST data.</li>

  </ul>
  • I am new to Django and web development all together and don't really understand what it means
  • please help me understand what is that I need to learn to fix this

UPDATE

My form looks like

<form class="new-playlist form-inline" onclick="event.stopPropagation()">{% csrf_token %}
     <input type="text" class="input-small">
     <button class="btn btn-danger create-playlist-button" type="submit" disabled="disabled">New</button>
</form>

UPDATE 1 After adding the code from Django CSRF check failing with an Ajax POST request I see post data as

csrfmiddlewaretoken {{ csrf_token }}
video_title The Who - Who Are You?
Source
video_title=The+Who+-+Who+Are+You%3F&csrfmiddlewaretoken=%7B%7B+csrf_token+%7D%7D

My jQuery now looks like

// setting up ajaxSetup
$(function(){
    $.ajaxSetup({ 
         beforeSend: function(xhr, settings) {
             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]);
                         // Does this cookie string begin with the name we want?
                     if (cookie.substring(0, name.length + 1) == (name + '=')) {
                         cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                         break;
                     }
                 }
             }
             return cookieValue;
             }
             if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                 // Only send the token to relative URLs i.e. locally.
                 xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
             }
         } 
    });
});
// creating new playlist
$(function() {
    // activate "New" buttons if input is not empty
    $('form input[type="text"]').live('keyup', function() {
        var val = $.trim(this.value);
        $(this).next("button").prop('disabled', val.length === 0);
    });

    $("body").on("submit","form",function(e){
        // do not submit the form
        e.preventDefault();

        // handle everything yourself
        var $form = $(this);
        var title = $form.closest('.video-detail').find('.title').text();
        var entryTitle = $form.find('.input-small').val();
        console.debug(title);
        console.debug(entryTitle);      

        // send the data to the server using .ajax() or .post()
        $.ajax({
            type: 'POST',
            url: 'addVideo',
            data: {
                video_title: title,
                csrfmiddlewaretoken: '{{ csrf_token }}'
                },
        }).done(function(){
            alert('done');
        });
    });
});

Thank you

Community
  • 1
  • 1
daydreamer
  • 87,243
  • 191
  • 450
  • 722

2 Answers2

0

Django is trying to protect you from CSRF by insisting that you provide a CSRF Token. Normally - if you are submitting a form via normal POST - it's very easy to enable, you just do the following:

<form action="." method="post">{% csrf_token %}

but because you are using AJAX, it's a bit more complicated. Have a look at the django docs for their recommendations or see a previous question dealing with the problem.

Essentially, you need to provide and submit the token manually when using AJAX but the best solution depends on your version of django it seems.

Community
  • 1
  • 1
Timmy O'Mahony
  • 53,000
  • 18
  • 155
  • 177
  • tried what you said @Timmy, but seems like `csrf_token` value is not being set, see another question that I asked http://stackoverflow.com/questions/11812694/jquery-setting-up-csrf-token-for-django-not-working – daydreamer Aug 04 '12 at 23:31
0

Try using passing the result $form.serialize() as the data for $.ajax(). As long as you have {% csrf_token %} present somewhere in your form template, this will pick all values in your form (including the token) and send in your AJAX call.

Michael Mior
  • 28,107
  • 9
  • 89
  • 113