J'ai un formulaire de téléchargement de plusieurs fichiers:
<input type="file" name="files" multiple />
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 du fichier AJAX est progress
ou onprogress
sur l'instance brute XmlHttpRequest
.
Ainsi, après chaque $.ajax()
, côté serveur (que je ne sais pas ce que vous allez utiliser), envoyez une réponse JSON pour exécuter le 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 le faire, dans la variable success
la $(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)').trigger('ajax');
$this.remove(); // remove the field so the next call won't resend the same field
}
});
}).trigger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each
Le code ci-dessus serait pour plusieurs <input type="file">
mais pas pour <input type="file" multiple>
, 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.trigger('ajax');
}
});
}).trigger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each
Cela ressemble à un très bon tutoriel, exactement ce que vous cherchez .
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 de iframe
. (I.E crée dynamiquement un iframe et 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 creuser avec sa 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:
Si vous utilisez nginx, vous pouvez également choisir de compiler avec leur Télécharger le module de progression
Tout cela fonctionne 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 quand est terminé.
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 + "<br>";
handleFile( files, ++index );
} else {
console.log( "Error" );
}
};
request.send( formData );
}
}
En utilisant ce code source, vous pouvez télécharger plusieurs fichiers, comme Google, un par un à travers ajax. Aussi, vous pouvez voir la progression du téléchargement
HTML
<input type="file" id="multiupload" name="uploadFiledd[]" multiple >
<button type="button" id="upcvr" class="btn btn-primary">Start Upload</button>
<div id="uploadsts"></div>
Javascript
<script>
function uploadajax(ttl,cl){
var fileList = $('#multiupload').prop("files");
$('#prog'+cl).removeClass('loading-prep').addClass('upload-image');
var form_data = "";
form_data = new FormData();
form_data.append("upload_image", fileList[cl]);
var request = $.ajax({
url: "upload.php",
cache: false,
contentType: false,
processData: false,
async: true,
data: form_data,
type: 'POST',
xhr: function() {
var xhr = $.ajaxSettings.xhr();
if(xhr.upload){
xhr.upload.addEventListener('progress', function(event){
var percent = 0;
if (event.lengthComputable) {
percent = Math.ceil(event.loaded / event.total * 100);
}
$('#prog'+cl).text(percent+'%')
}, false);
}
return xhr;
}
})
.success(function(res,status) {
if(status == 'success'){
percent = 0;
$('#prog'+cl).text('');
$('#prog'+cl).text('--Success: ');
if(cl < ttl){
uploadajax(ttl,cl+1);
}else{
alert('Done ');
}
}
})
.fail(function(res) {
alert('Failed');
});
}
$('#upcvr').click(function(){
var fileList = $('#multiupload').prop("files");
$('#uploadsts').html('');
var i
for ( i = 0; i < fileList.length; i++) {
$('#uploadsts').append('<p class="upload-page">'+fileList[i].name+'<span class="loading-prep" id="prog'+i+'"></span></p>');
if(i == fileList.length-1){
uploadajax(fileList.length-1,0);
}
}
});
</script>
PHP
upload.php
move_uploaded_file($_FILES["upload_image"]["tmp_name"],$_FILES["upload_image"]["name"]);