chakku
chakku

Reputation: 57

Django-ajax: CSRF verification failed. Request aborted

I am working with django server side form to save details in DB.

<form id="form_save_file" enctype="multipart/form-data">
{% csrf_token %}
      <label class="control-label col-md-4">File:</label>
        <div class="col-md-8">
            {{form.fa_file}}
        </div>
      <label class="control-label col-md-4">Name:</label>
        <div class="col-md-8">
            {{form.name}}
        </div>
</form>

I am using ajax to post request.

$("#form_save_file").submit(function(e) {
        $.ajax({

           type: "POST",
           url: '/url/',
           data: $("#form_save_file").serialize(),
           contentType: false, 
           processData: false,
           success: function(data){}
});

I have included middleware classes in settings.py

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'request.middleware.RequestMiddleware'
)

When I removed contentType and processData in ajax request, request.FILES is empty in views.py and otherthings are working fine.

Upvotes: 0

Views: 1245

Answers (2)

Saurabh Chandra Patel
Saurabh Chandra Patel

Reputation: 13644

disabled csrf on particular view with @csrf_exempt decorator and build custom security with a random number/string

Upvotes: 0

Hybrid
Hybrid

Reputation: 7049

contentType option to false is used for multipart/form-data forms that pass files.

When one sets the contentType option to false, it forces jQuery not to add a Content-Type header, otherwise, the boundary string will be missing from it. Also, when submitting files via multi-part/form one must leave the processData flag set to false, otherwise, jQuery will try to convert your FormData into a string, which will fail.

To try and fix your issue:

You are using jQuery's .serialize() method which creates a text string in standard URL-encoded notation.

You need to pass un-encoded data when using "contentType: false".

Try using "new FormData" instead of .serialize():

Source: https://stackoverflow.com/a/20863123/3345051

Revised Code:

$("#form_save_file").submit(function(e) {

    e.preventDefault();

    var $this = $(this);
    var postURL = '/url/';
    var formData = new FormData(this);


    $.ajax({
           type: "POST",
           url: postURL,
           data: formData,
           mimeType: "multipart/form-data",
           contentType: false,
           cache: false,
           processData: false
    })
    .done(function(response) {
        // Do something if POST is successful
    })
    .fail(function() {
        // Do something if POST is unsuccessful
    })

})

Upvotes: 2

Related Questions