Téléchargement de plusieurs fichiers HTML5: téléchargez un par un via AJAX

J’ai un formulaire de téléchargement de plusieurs fichiers:

 

Je poste ces fichiers avec ajax. Je souhaite télécharger les fichiers sélectionnés un par un (pour créer des barres de progression individuelles et par curiosité).

Je peux obtenir la liste des fichiers ou des fichiers individuels en

 FL = form.find('[type="file"]')[0].files F = form.find('[type="file"]')[0].files[0] 

Yieling

 FileList { 0=File, 1=File, length=2 } File { size=177676, type="image/jpeg", name="img.jpg", more...} 

Mais FileList est immuable et je ne vois pas comment soumettre un fichier unique.

Je pense que cela est possible car j’ai vu http://blueimp.github.com/jQuery-File-Upload/ . Je ne veux cependant pas utiliser ce plugin, car il s’agit autant de l’apprentissage que du résultat (et il faudrait de toute façon trop de personnalisation). Je ne veux pas non plus utiliser Flash.

Pour que cette opération soit synchrone, vous devez lancer le nouveau transfert à la fin du dernier transfert. Gmail, par exemple, envoie tout en même temps, simultanément. L’événement pour la progression du téléchargement de fichier AJAX est progress ou progress sur l’instance brute XmlHttpRequest .

Donc, après chaque $.ajax() , côté serveur (ce que je ne sais pas ce que vous allez utiliser), envoyez une réponse JSON pour exécuter AJAX à la prochaine entrée. Une option consisterait à lier l’élément AJAX à chaque élément, pour faciliter les choses, afin que vous puissiez simplement faire, en cas de success le $(this).sibling('input').execute_ajax() .

Quelque chose comme ça:

 $('input[type="file"]').on('ajax', function(){ var $this = $(this); $.ajax({ 'type':'POST', 'data': (new FormData()).append('file', this.files[0]), 'contentType': false, 'processData': false, 'xhr': function() { var xhr = $.ajaxSettings.xhr(); if(xhr.upload){ xhr.upload.addEventListener('progress', progressbar, false); } return xhr; }, 'success': function(){ $this.siblings('input[type="file"]:eq(0)').sortinggger('ajax'); $this.remove(); // remove the field so the next call won't resend the same field } }); }).sortinggger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each 

Le code ci-dessus serait pour plusieurs mais pas pour , dans ce cas, il devrait être:

 var count = 0; $('input[type="file"]').on('ajax', function(){ var $this = $(this); if (typeof this.files[count] === 'undefined') { return false; } $.ajax({ 'type':'POST', 'data': (new FormData()).append('file', this.files[count]), 'contentType': false, 'processData': false, 'xhr': function() { var xhr = $.ajaxSettings.xhr(); if(xhr.upload){ xhr.upload.addEventListener('progress', progressbar, false); } return xhr; }, 'success': function(){ count++; $this.sortinggger('ajax'); } }); }).sortinggger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each 

Cela ressemble à un très bon tutoriel, exactement ce que vous recherchez .

Cela dit, le téléchargement via vanilla ajax n’est pas pris en charge par tous les navigateurs, et je recommanderais quand même l’utilisation d’un iframe . (IE crée dynamicment un iframe et le POST en utilisant javascript)

J’ai toujours utilisé ce script et je le trouve très concis. Si vous souhaitez apprendre à télécharger en créant un iframe, vous devez explorer son source.

J’espère que ça aide 🙂

Extra edit

Pour créer des barres de progression avec la méthode iframe, vous devez effectuer certaines tâches côté serveur. Si vous utilisez php, vous pouvez utiliser:

  • Progression de l’envoi de session pour php5.4 +
  • Télécharger le package de progression pour php <5.4

Si vous utilisez nginx, vous pouvez également choisir de comstackr avec leur module de progression de téléchargement.

Tous ces éléments fonctionnent de la même manière – chaque téléchargement a un UID, vous demanderez la «progression» associée à cet ID à des intervalles cohérents via ajax. Cela renverra la progression du téléchargement telle que déterminée par le serveur.

Je faisais face au même problème et suis venu avec cette solution. Je récupère simplement le formulaire avec multipart, et en appel récursif (fichier après fichier), lance la demande ajax, qui appelle seulement ensuite quand est fait.

 var form = document.getElementById( "uploadForm" ); var fileSelect = document.getElementById( "photos" ); var uploadDiv = document.getElementById( "uploads" ); form.onsubmit = function( event ) { event.preventDefault( ); var files = fileSelect.files; handleFile( files, 0 ); }; function handleFile( files, index ) { if( files.length > index ) { var formData = new FormData( ); var request = new XMLHttpRequest( ); formData.append( 'photo', files[ index ] ); formData.append( 'serial', index ); formData.append( 'upload_submit', true ); request.open( 'POST', 'scripts/upload_script.php', true ); request.onload = function( ) { if ( request.status === 200 ) { console.log( "Uploaded" ); uploadDiv.innerHTML += files[ index ].name + "
"; handleFile( files, ++index ); } else { console.log( "Error" ); } }; request.send( formData ); } }

En utilisant ce code source, vous pouvez télécharger plusieurs fichiers tels que Google un par un via ajax. Aussi, vous pouvez voir la progression du téléchargement

HTML

    

Javascript

  

PHP

 upload.php move_uploaded_file($_FILES["upload_image"]["tmp_name"],$_FILES["upload_image"]["name"]);