14

I know, the topics aren't missing on this subject but bear with me. I'd like to upload a file to the server using Ajax or an equivalent.

# html
<form method="post" id="Form" enctype="multipart/form-data">
  {% csrf_token %} # django security
  <input id="image_file" type="file" name="image_file">
  <input type="submit" value="submit">
</form>

# javascript
$(document).on('submit', '#Form', function(e){
  e.preventDefault();

  var form_data = new FormData();
  form_data.append('file', $('#image_file').get(0).files);

  $.ajax({
      type:'POST',
      url:'my_url',
      processData: false,
      contentType: false,
      data:{
          logo:form_data,
          csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), # django security
      },
  });
});

# views.py (server side)
def myFunction(request):
    if request.method == 'POST':
        image_file = request.FILES
        ...
...

I guess there's an issue with the way I configured the ajax function since on debug mode, every data are returned except the logo.

Am I doing something incorrectly?

3 Answers 3

15

The below method works for me, it will submit all form value as serialize(). You will get all form input's inside request.POST and logo request.FILES

Try this:

$(document).on('submit', '#creationOptionsForm', function(e){
  e.preventDefault();

  var form_data = new FormData($('#creationOptionsForm')[0]);
  $.ajax({
      type:'POST',
      url:'/designer/results/',
      processData: false,
      contentType: false,
      async: false,
      cache: false,
      data : form_data,
      success: function(response){

      }
  });
});

Update:

basically async:false will do ajax request and stop executing further js code till the time request get complete, because upload file might take some time to upload to server.

While cache will force browser to not cache uploaded data to get updated data in ajax request

Official Documentation here

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

2 Comments

You do not need async: false anymore (on the contrary: if you set it, you'll get a warning in the Chrome console)
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check xhr.spec.whatwg.org.
6

Looking back, the older answer is unpractical and not recommended. async: false pauses the entire Javascript to simply upload a file, you are likely firing other functions during the upload.

If you are using JQuery solely for the use of ajax, then I recommend using axios:

const axios = require('axios');

var formData = new FormData();
formData.append('imageFile', document.querySelector('#image_file').files[0]);

axios({
    method: 'post',
    url: 'your_url',
    data: formData,
    headers: {
        "X-CSRFToken": CSRF_TOKEN, # django security
        "content-type": "multipart/form-data"
    }
}).then(function (response) {
    # success
});

Axios Documentation


Jquery/Ajax answer:

var formData = new FormData();
formData.append('imageFile', $('#image_file')[0].files[0]);
formData.append('csrfmiddlewaretoken', CSRF_TOKEN); # django security

$.ajax({
   url : 'your_url',
   type : 'POST',
   data : formData,
   processData: false,
   contentType: false,
   success : function(data) {
       # success
   }
});

Jquery/Ajax Documentation

Comments

1

Update: We can use native fetch in all current browsers

const formData = new FormData();
formData.append('imageFile', document.getElementById('image_file').files[0]);

fetch('your_url', {
    method: 'POST',
    body: formData,
    headers: { "X-CSRFToken": CSRF_TOKEN, // Django security  }, // remove for a normal post
})
.then(response => response.json()) // or response.text() if the server returns plain text
.then(data => console.log(data)) // replace with whatever you want to happen after the upload
.catch(error =>console.error('Error:', error));

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.