web-dev-qa-db-fra.com

Comment télécharger un fichier en utilisant Ajax sur POST?

Je sais, les sujets ne manquent pas à ce sujet mais supportez-moi. Je voudrais télécharger un fichier sur le serveur en utilisant Ajax ou un équivalent.

# 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
        ...
...

Je suppose qu'il y a un problème avec la façon dont j'ai configuré la fonction ajax car en mode débogage, toutes les données sont retournées sauf le logo.

Suis-je en train de faire quelque chose de mal?

11
Hiroyuki Nuri

Avec le recul, l'ancienne réponse n'est pas pratique et n'est pas recommandée. asnyc: false met en pause l'intégralité du Javascript pour simplement télécharger un fichier, vous exécutez probablement d'autres fonctions pendant le téléchargement.

Si vous utilisez JQuery uniquement pour l'utilisation de ajax, je vous recommande d'utiliser 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


Réponse Jquery/Ajax:

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

3
Hiroyuki Nuri

La méthode ci-dessous fonctionne pour moi, elle soumettra toutes les valeurs du formulaire en tant que serialize(). Vous obtiendrez toutes les entrées de formulaire à l'intérieur request.POST et logo request.FILES

Essayez ceci:

$(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){

      }
  });
});

Mise à jour:

fondamentalement async:false exécutera la requête ajax et cessera d'exécuter du code js supplémentaire jusqu'à ce que la requête soit terminée, car le téléchargement du fichier peut prendre un certain temps à télécharger sur le serveur.

Alors que cache forcera le navigateur à ne pas mettre en cache les données téléchargées pour obtenir les données mises à jour dans la demande ajax

Documentation officielle ici

12