How to upload a file using Ajax on POST?
Asked Answered
E

3

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?

Eglanteen answered 22/6, 2017 at 19:39 Comment(0)
E
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

Eglanteen answered 29/3, 2019 at 10:34 Comment(0)
H
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

Honey answered 22/6, 2017 at 19:52 Comment(2)
You do not need async: false anymore (on the contrary: if you set it, you'll get a warning in the Chrome console)Velarize
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.Chinatown
E
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

Eglanteen answered 29/3, 2019 at 10:34 Comment(0)
O
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));
Oddfellow answered 29/3 at 9:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.