Comment puis-je télécharger des fichiers de manière asynchrone?

2914

Je souhaite télécharger un fichier de manière asynchrone avec jQuery.

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

Au lieu de télécharger le fichier, je ne reçois que le nom de fichier. Que puis-je faire pour résoudre ce problème?

Sergio del Amo
la source
Il existe différents plugins prêts à l'emploi pour le téléchargement de fichiers pour jQuery. Faire ce type de téléchargement de hacks n'est pas une expérience agréable, donc les gens aiment utiliser des solutions prêtes à l'emploi. En voici quelques-uns: - JQuery File Uploader - Multiple File Upload Plugin - Mini Multiple File Upload - jQuery File Upload Vous pouvez rechercher plus de projets sur NPM (en utilisant "jquery-plugin" comme mot-clé) ou sur Github.
Joyeux
72
vous obtenez uniquement le nom du fichier parce que votre nom de fichier var obtient la valeur de $ ('# fichier'), pas le fichier qui se trouve dans l'entrée
Jimmy
21
En voici une bonne: http://blueimp.github.io/jQuery-File-Upload/ - Téléchargement ajax HTML5 - Remplacement gracieux des iframes pour les navigateurs non pris en charge - Téléchargement asynchrone multi-fichiers Nous l'avons utilisé et cela fonctionne très bien. ( Documentation ici )
Ashish Panery
3
Vérifiez également ceci: stackoverflow.com/questions/6974684/… , ici il explique comment y parvenir via jQuery
Chococroc
2
@Jimmy Comment pourrait-il obtenir le fichier qui se trouve à la place?
alex

Réponses:

2519

Avec HTML5, vous pouvez effectuer des téléchargements de fichiers avec Ajax et jQuery. Non seulement cela, vous pouvez effectuer des validations de fichiers (nom, taille et type MIME) ou gérer l'événement de progression avec la balise de progression HTML5 (ou un div). Récemment, j'ai dû faire un téléchargeur de fichiers, mais je ne voulais pas utiliser Flash, ni Iframes ni plugins et après quelques recherches, j'ai trouvé la solution.

Le HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

Tout d'abord, vous pouvez effectuer une validation si vous le souhaitez. Par exemple, en .on('change')cas de fichier:

$(':file').on('change', function () {
  var file = this.files[0];

  if (file.size > 1024) {
    alert('max upload size is 1k');
  }

  // Also see .name, .type
});

Maintenant, $.ajax()soumettez avec le clic du bouton:

$(':button').on('click', function () {
  $.ajax({
    // Your server script to process the upload
    url: 'upload.php',
    type: 'POST',

    // Form data
    data: new FormData($('form')[0]),

    // Tell jQuery not to process data or worry about content-type
    // You *must* include these options!
    cache: false,
    contentType: false,
    processData: false,

    // Custom XMLHttpRequest
    xhr: function () {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        // For handling the progress of the upload
        myXhr.upload.addEventListener('progress', function (e) {
          if (e.lengthComputable) {
            $('progress').attr({
              value: e.loaded,
              max: e.total,
            });
          }
        }, false);
      }
      return myXhr;
    }
  });
});

Comme vous pouvez le voir, le téléchargement de fichiers HTML5 (et certaines recherches) devient non seulement possible, mais super facile. Essayez-le avec Google Chrome, car certains des composants HTML5 des exemples ne sont pas disponibles dans tous les navigateurs.

olanod
la source
14
Puis-je ensuite utiliser $ _FILES dans le fichier upload.php?
Alessandro Cosentino
71
Cela devrait fonctionner dans Internet Explorer mais uniquement dans la version 10. ( caniuse.com/xhr2 )
Tyler
18
Salut, j'apprécie que PHP soit votre langue de choix ... mais je me demande si vous savez si cela fonctionne aussi dans ASP.NET MVC? Je suis un développeur .NET et j'ai essayé d'utiliser votre exemple simple pour télécharger des fichiers AJAX, mais côté serveur, je ne reçois pas le fichier que j'ai publié via AJAX. J'utilise la dernière version de Chrome.
Shumii
25
C'est FormData qui fait toute la magie ici. Assurez-vous de vérifier ces documents - cela couvre toutes vos questions sur plusieurs fichiers et champs.
incarné le
4
Juste pour que quelqu'un d'autre ne passe pas des heures ... name="file"c'est très important sur la <input>balise de fichier si vous allez utiliser les données en PHP (et probablement à d'autres endroits). J'ai créé un formulaire dynamiquement en utilisant javascript, donc je n'ai pas eu besoin de l'attribut name, mais j'ai découvert que vous en avez absolument besoin pour récupérer les données côté serveur.
Kivak Wolf du
273

Mise à jour 2019: cela dépend toujours des navigateurs que votre démographie utilise.

Une chose importante à comprendre avec la "nouvelle" fileAPI HTML5 est qu'elle n'était pas prise en charge avant IE 10 . Si le marché spécifique que vous visez a une propension plus élevée que la moyenne aux anciennes versions de Windows, vous pourriez ne pas y avoir accès.

En 2017, environ 5% des navigateurs sont des IE 6, 7, 8 ou 9. Si vous vous dirigez vers une grande entreprise (par exemple, c'est un outil B2B ou quelque chose que vous proposez pour la formation), ce nombre peut monter en flèche . En 2016, j'ai traité avec une entreprise utilisant IE8 sur plus de 60% de leurs machines.

C'est 2019 à partir de cette édition, près de 11 ans après ma réponse initiale. IE9 et inférieurs sont globalement autour de la barre des 1%, mais il existe toujours des grappes d'utilisation plus élevée.

L'important point à retenir de cela, quelle que soit la fonctionnalité, est de vérifier quel navigateur vos utilisateurs utilisent . Si vous ne le faites pas, vous apprendrez une leçon rapide et douloureuse sur la raison pour laquelle «fonctionne pour moi» n'est pas assez bon dans un livrable à un client. caniuse est un outil utile, mais notez d'où ils tirent leurs données démographiques. Ils peuvent ne pas correspondre au vôtre. Ce n'est jamais plus vrai que les environnements d'entreprise.

Ma réponse de 2008 suit.


Cependant, il existe des méthodes viables non JS de téléchargement de fichiers. Vous pouvez créer un iframe sur la page (que vous masquez avec CSS), puis cibler votre formulaire pour le publier sur cet iframe. La page principale n'a pas besoin de bouger.

C'est un "vrai" article donc il n'est pas entièrement interactif. Si vous avez besoin d'un statut, vous avez besoin de quelque chose côté serveur pour le traiter. Cela varie considérablement en fonction de votre serveur. ASP.NET a de meilleurs mécanismes. PHP plaine échoue, mais vous pouvez utiliser des modifications Perl ou Apache pour le contourner.

Si vous avez besoin de plusieurs téléchargements de fichiers, il est préférable de faire chaque fichier un par un (pour dépasser les limites maximales de téléchargement de fichiers). Publiez le premier formulaire dans l'iframe, surveillez sa progression à l'aide de ce qui précède et, une fois terminé, publiez le deuxième formulaire dans l'iframe, etc.

Ou utilisez une solution Java / Flash. Ils sont beaucoup plus flexibles dans ce qu'ils peuvent faire avec leurs messages ...

Oli
la source
142
Pour mémoire, il est maintenant possible de faire des téléchargements de fichiers AJAX purs si le navigateur prend en charge l'API File - developer.mozilla.org/en/using_files_from_web_applications
meleyal
La solution iframe est assez simple et facile à travailler
Matthew Lock
c'est une assez vieille réponse, mais c'était un peu trompeur. IE supportait XHR nativement depuis IE7, et le supportait via ActiveX depuis IE5. w3schools.com/ajax/ajax_xmlhttprequest_create.asp . La manière pratique de le faire était certainement de cibler des composants flash (shockwave) ou de déployer un contrôle Flash / ActiveX (Silverlight). Si vous pouvez lancer une requête et gérer la réponse via javascript, c'est ajax .. bien que cela ait été dit, ajax est synonyme de xhr, mais il ne décrit pas lui-même le mécanisme / composants de soulignement qui fournit / échange la charge utile.
Brett Caswell
4
@BrettCaswell Je ne disais pas que AJAX / XHR n'était pas possible, juste qu'il n'était pas possible de publier un fichier avec eux sur d'anciennes versions - mais toujours vivantes - d'IE. Cela était et reste tout à fait vrai.
Oli
Ce n'est pas comme ça, c'est une opinion UX - validez-la peut-être.
Nimjox
112

Je recommande d'utiliser le plugin Fine Uploader à cet effet. Votre JavaScriptcode serait:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});
Shiladitya
la source
Il utilise JSON - donc pour l'ancienne version PHP, ce ne sera pas possible.
Lorenzo Manucci
Semble beaucoup plus propre que Ajax File Upload, où je dois inclure un énorme morceau de code juste pour utiliser la fichue chose.
ripper234
La nouvelle URL de la version 2 est désormais valums-file-uploader.github.com/file-uploader
Simon East
35
"Ce plugin est open source sous GNU GPL 2 ou version ultérieure et GNU LGPL 2 ou version ultérieure." Donc, tant que vous ne distribuez pas la copie ou une version modifiée, vous n'avez pas besoin d'ouvrir votre projet.
Trantor Liu
Suis-je en train de manquer quelque chose? Cette bibliothèque ne semble plus utiliser jquery, donc elle ne supporte pas la syntaxe de la réponse?
James McCormack
102

Remarque: Cette réponse est obsolète, il est désormais possible de télécharger des fichiers à l'aide de XHR.


Vous ne pouvez pas télécharger de fichiers à l'aide de XMLHttpRequest (Ajax). Vous pouvez simuler l'effet à l'aide d'un iframe ou d'un flash. L'excellent plugin jQuery Form qui publie vos fichiers via un iframe pour obtenir l'effet.

Mattias
la source
1
Oui, vous pouvez POSTER vers un iframe et y capturer le fichier. J'ai cependant une expérience très limitée avec cela, donc je ne peux pas vraiment commenter cela.
Mattias
15
Petite remarque: dans les dernières versions de Chrome et Firefox, c'est possible, stackoverflow.com/questions/4856917/…
Alleo
Non pris en charge dans IE9 et moins
Radmation
96

Conclusion pour les futurs lecteurs.

Téléchargement de fichier asynchrone

Avec HTML5

Vous pouvez télécharger des fichiers avec jQuery en utilisant la $.ajax()méthode si FormData et l' API File sont pris en charge (les deux fonctionnalités HTML5).

Vous pouvez également envoyer des fichiers sans FormData mais dans tous les cas l'API File doit être présente pour traiter les fichiers de telle manière qu'ils puissent être envoyés avec XMLHttpRequest (Ajax).

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Pour un exemple rapide et pur de JavaScript ( pas de jQuery ), voir " Envoi de fichiers à l'aide d'un objet FormData ".

Se retirer

Lorsque HTML5 n'est pas pris en charge (pas d' API de fichier ), la seule autre solution JavaScript pure (pas de Flash ou tout autre plugin de navigateur) est la technique iframe cachée , qui permet d'émuler une demande asynchrone sans utiliser l' objet XMLHttpRequest .

Il consiste à définir un iframe comme cible du formulaire avec les entrées de fichier. Lorsque l'utilisateur soumet une demande est faite et les fichiers sont téléchargés mais la réponse est affichée à l'intérieur de l'iframe au lieu de restituer la page principale. Masquer l'iframe rend l'ensemble du processus transparent pour l'utilisateur et émule une demande asynchrone.

Si cela est fait correctement, cela devrait fonctionner pratiquement sur n'importe quel navigateur, mais il a quelques mises en garde sur la façon d'obtenir la réponse de l'iframe.

Dans ce cas, vous préférerez peut-être utiliser un plugin wrapper comme Bifröst qui utilise la technique iframe mais fournit également un transport jQuery Ajax permettant d' envoyer des fichiers avec juste la $.ajax()méthode comme celle-ci:

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Plugins

Bifröst n'est qu'un petit wrapper qui ajoute une prise en charge de secours à la méthode ajax de jQuery, mais de nombreux plugins susmentionnés comme jQuery Form Plugin ou jQuery File Upload incluent la pile entière de HTML5 vers différentes solutions de secours et certaines fonctionnalités utiles pour faciliter le processus. Selon vos besoins et exigences, vous voudrez peut-être envisager une implémentation nue ou l'un de ces plugins.

404
la source
3
Une chose à noter, basée sur la documentation: vous devez également envoyer contentType: false. Lorsque je n'ai pas envoyé cela avec Chrome, le type de contenu du formulaire a été invalidé par jQuery.
ash
Bonne réponse. Quelques suggestions d'amélioration: Supprimez les parties du code sans rapport avec la réponse, par exemple le .done()et les .fail()rappels. De plus, un exemple sans l'utilisation de FormDataet une liste des avantages / inconvénients serait génial.
Zero3
J'ai eu cette erreur:TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
candlejack
85

Ce plugin jQuery de téléchargement de fichier AJAX télécharge le fichier quelque part, et transmet la réponse à un rappel, rien d'autre.

  • Cela ne dépend pas d'un HTML spécifique, donnez-lui simplement un <input type="file">
  • Il ne nécessite pas que votre serveur réponde d'une manière particulière
  • Peu importe le nombre de fichiers que vous utilisez ou leur emplacement sur la page

- Utilisez aussi peu que -

$('#one-specific-file').ajaxfileupload({
  'action': '/upload.php'
});

- ou autant que -

$('input[type="file"]').ajaxfileupload({
  'action': '/upload.php',
  'params': {
    'extra': 'info'
  },
  'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  },
  'onStart': function() {
    if(weWantedTo) return false; // cancels upload
  },
  'onCancel': function() {
    console.log('no file selected');
  }
});
Jordan Feldstein
la source
1
@ user840250 jQuery 1.9.1?
Jordan Feldstein
62

J'utilise le script ci-dessous pour télécharger des images qui fonctionnent correctement.

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

Javascript

jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

Explication

J'utilise la réponse divpour montrer l'animation de téléchargement et la réponse une fois le téléchargement terminé.

La meilleure partie est que vous pouvez envoyer des données supplémentaires telles que les identifiants, etc. avec le fichier lorsque vous utilisez ce script. Je l'ai mentionné extra-datacomme dans le script.

Au niveau PHP, cela fonctionnera comme un téléchargement de fichier normal. les données supplémentaires peuvent être récupérées en tant que $_POSTdonnées.

Ici, vous n'utilisez pas de plugin et d'autres choses. Vous pouvez modifier le code comme vous le souhaitez. Vous ne codez pas aveuglément ici. Il s'agit de la fonctionnalité principale de tout téléchargement de fichier jQuery. En fait, Javascript.

Techie
la source
5
-1 pour utiliser jQuery et ne pas utiliser son moteur de sélection et ses gestionnaires d'événements. addEventListenern'est pas multi-navigateur.
Mark
3
Parce qu'il serait inutile d'ajouter une réponse distincte qui serait principalement basée sur celle-ci, avec seulement quelques changements. Au lieu de cela, cette réponse devrait être corrigée.
Mark
2
@RainFromHeaven, s'il vous plaît, pouvez-vous modifier la réponse? Je ne sais pas comment le faire de manière multi-navigateur.
Thiago Negri
2
Ne fonctionne toujours pas dans IE 9 et les versions antérieures. Beaucoup d'utilisateurs utilisent toujours ces versions d'IE.
Pierre
1
Quelqu'un peut-il expliquer comment cela peut fonctionner sur asp.net? Dois-je utiliser la méthode Web? Si oui, à quoi cela ressemblerait-il?
SamuraiJack
49

Vous pouvez le faire en JavaScript vanille assez facilement. Voici un extrait de mon projet actuel:

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
    var percent = (e.position/ e.totalSize);
    // Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
    if(this.readyState === 4) {
        // Handle file upload complete
    }
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);
mpen
la source
3
@Gary: Désolé, j'aurais dû publier ce morceau aussi. J'utilisais juste la nouvelle fonctionnalité de glisser-déposer en HTML5; vous pouvez trouver un exemple ici: html5demos.com/file-api#view-source - cliquez simplement sur "voir la source". Essentiellement, à l'intérieur de l' ondropévénement, vous pouvez le fairevar file = e.dataTransfer.files[0]
mpen
Peut-être que la question a été modifiée depuis, mais certaines personnes sur une discussion que j'ai ouverte pensent qu'une réponse JS vanille est hors sujet si OP demande une solution jQuery (s'il en existe une) et que ces réponses appartiennent à une question distincte.
Andy
4
@Andy Eh bien, je ne suis pas d'accord, et il semble que 34 autres personnes le fassent aussi. Si vous pouvez utiliser jQuery, vous pouvez certainement utiliser JavaScript. En tout cas, c'est un site communautaire - ce n'est pas seulement OP que j'essaie d'aider ici. Chacun est libre de choisir / utiliser la réponse qu'il préfère. Certaines personnes gravitent simplement vers jQuery parce qu'elles pensent que ce sera beaucoup plus facile / moins de lignes de code, alors qu'en réalité, elles n'ont pas du tout besoin de la surcharge d'une bibliothèque supplémentaire.
mpen
47

Vous pouvez télécharger simplement avec jQuery .ajax().

HTML:

<form id="upload-form">
    <div>
        <label for="file">File:</label>
        <input type="file" id="file" name="file" />
        <progress class="progress" value="0" max="100"></progress>
    </div>
    <hr />
    <input type="submit" value="Submit" />
</form>

CSS

.progress { display: none; }

Javascript:

$(document).ready(function(ev) {
    $("#upload-form").on('submit', (function(ev) {
        ev.preventDefault();
        $.ajax({
            xhr: function() {
                var progress = $('.progress'),
                    xhr = $.ajaxSettings.xhr();

                progress.show();

                xhr.upload.onprogress = function(ev) {
                    if (ev.lengthComputable) {
                        var percentComplete = parseInt((ev.loaded / ev.total) * 100);
                        progress.val(percentComplete);
                        if (percentComplete === 100) {
                            progress.hide().val(0);
                        }
                    }
                };

                return xhr;
            },
            url: 'upload.php',
            type: 'POST',
            data: new FormData(this),
            contentType: false,
            cache: false,
            processData: false,
            success: function(data, status, xhr) {
                // ...
            },
            error: function(xhr, status, error) {
                // ...
            }
       });
    }));
});
Zayn Ali
la source
1
@RaydenBlack uniquement jQuery.
Zayn Ali
comment obtenir la progression du téléchargement?
Ali Sherafat
44

La manière la plus simple et la plus robuste que j'ai faite dans le passé, consiste simplement à cibler une balise iFrame cachée avec votre formulaire - puis elle sera soumise dans l'iframe sans recharger la page.

C'est-à-dire si vous ne voulez pas utiliser un plugin, JavaScript ou toute autre forme de "magie" autre que HTML. Bien sûr, vous pouvez combiner cela avec JavaScript ou ce que vous avez ...

<form target="iframe" action="" method="post" enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

<iframe name="iframe" id="iframe" style="display:none" ></iframe>

Vous pouvez également lire le contenu de l'iframe onLoadpour les erreurs de serveur ou les réponses réussies, puis les transmettre à l'utilisateur.

Chrome, iFrames et onLoad

-note- vous ne devez continuer à lire que si vous êtes intéressé par la façon de configurer un bloqueur d'interface utilisateur lors du téléchargement / téléchargement

Actuellement, Chrome ne déclenche pas l'événement onLoad pour l'iframe lorsqu'il est utilisé pour transférer des fichiers. Firefox, IE et Edge déclenchent tous l'événement onload pour les transferts de fichiers.

La seule solution que j'ai trouvée compatible avec Chrome était d'utiliser un cookie.

Pour ce faire, essentiellement lorsque le téléchargement / téléchargement est démarré:

  • [Côté client] Commencez un intervalle pour rechercher l'existence d'un cookie
  • [Côté serveur] Faites tout ce dont vous avez besoin avec les données du fichier
  • [Côté serveur] Définir un cookie pour l'intervalle côté client
  • [Côté client] Interval voit le cookie et l'utilise comme l'événement onLoad. Par exemple, vous pouvez démarrer un bloqueur d'interface utilisateur, puis onLoad (ou lorsqu'un cookie est créé) vous supprimez le bloqueur d'interface utilisateur.

L'utilisation d'un cookie pour cela est moche mais cela fonctionne.

J'ai créé un plugin jQuery pour gérer ce problème pour Chrome lors du téléchargement, vous pouvez le trouver ici

https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js

Le même principe de base s'applique également au téléchargement.

Pour utiliser le téléchargeur (y compris le JS, évidemment)

 $('body').iDownloader({
     "onComplete" : function(){
          $('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
     }
 });

 $('somebuttion').click( function(){
      $('#uiBlocker').css('display', 'block'); //block the UI
      $('body').iDownloader('download', 'htttp://example.com/location/of/download');
 });

Et côté serveur, juste avant de transférer les données du fichier, créez le cookie

 setcookie('iDownloader', true, time() + 30, "/");

Le plugin verra le cookie, puis déclenchera le onCompleterappel.

ArtisticPhoenix
la source
3
J'aime cela. Si seulement quelqu'un pouvait mentionner les problèmes potentiels de cette brillante solution. Je ne comprends vraiment pas pourquoi les gens utilisent et utilisent ces bibliothèques et plugins maladroits quand il y a la solution.
Yevgeniy Afanasyev
1
Eh bien, je suppose que la raison serait d'afficher des informations de progression lors du téléchargement.
Prakhar Mishra
32

Une solution que j'ai trouvée était d'avoir le <form> cible un iFrame caché. L'iFrame peut ensuite exécuter JS pour indiquer à l'utilisateur qu'il est terminé (au chargement de la page).

Darryl Hein
la source
1
je suis intéressé par cette réponse, avez-vous une démo à laquelle vous pouvez créer un lien?
lfender6445
32

J'ai écrit ceci dans un environnement Rails . Il ne s'agit que de cinq lignes de JavaScript, si vous utilisez le plugin léger jQuery-form.

Le défi consiste à faire fonctionner le téléchargement AJAX car la norme remote_form_forne comprend pas la soumission de formulaires en plusieurs parties. Il ne va pas envoyer le fichier que Rails recherche avec la demande AJAX.

C'est là que le plugin jQuery-form entre en jeu.

Voici le code Rails pour cela:

<% remote_form_for(:image_form, 
                   :url => { :controller => "blogs", :action => :create_asset }, 
                   :html => { :method => :post, 
                              :id => 'uploadForm', :multipart => true }) 
                                                                        do |f| %>
 Upload a file: <%= f.file_field :uploaded_data %>
<% end %>

Voici le JavaScript associé:

$('#uploadForm input').change(function(){
 $(this).parent().ajaxSubmit({
  beforeSubmit: function(a,f,o) {
   o.dataType = 'json';
  },
  complete: function(XMLHttpRequest, textStatus) {
   // XMLHttpRequest.responseText will contain the URL of the uploaded image.
   // Put it in an image element you create, or do with it what you will.
   // For example, if you have an image elemtn with id "my_image", then
   //  $('#my_image').attr('src', XMLHttpRequest.responseText);
   // Will set that image tag to display the uploaded image.
  },
 });
});

Et voici l'action du contrôleur Rails, jolie vanille:

 @image = Image.new(params[:image_form])
 @image.save
 render :text => @image.public_filename

Je l'utilise depuis quelques semaines avec Bloggity, et cela fonctionne comme un champion.

wbharding
la source
31

Simple Ajax Uploader est une autre option:

https://github.com/LPology/Simple-Ajax-Uploader

  • Cross-browser - fonctionne dans IE7 +, Firefox, Chrome, Safari, Opera
  • Prend en charge plusieurs téléchargements simultanés - même dans les navigateurs non HTML5
  • Pas de flash ou CSS externe - juste un fichier Javascript de 5 Ko
  • Prise en charge intégrée en option des barres de progression entièrement inter-navigateurs (en utilisant l'extension APC de PHP)
  • Flexible et hautement personnalisable - utilisez n'importe quel élément comme bouton de téléchargement, créez vos propres indicateurs de progression
  • Aucun formulaire requis, il suffit de fournir un élément qui servira de bouton de téléchargement
  • Licence MIT - libre d'utilisation dans un projet commercial

Exemple d'utilisation:

var uploader = new ss.SimpleUpload({
    button: $('#uploadBtn'), // upload button
    url: '/uploadhandler', // URL of server-side upload handler
    name: 'userfile', // parameter name of the uploaded file
    onSubmit: function() {
        this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
    },
    onComplete: function(file, response) {
        // do whatever after upload is finished
    }
});
user1091949
la source
2
Cela semble être le plus prometteur jusqu'à présent, vous m'avez eu à IE7+! L'essayer maintenant. Merci
Pierre
25

jQuery Uploadify est un autre bon plugin que j'ai utilisé auparavant pour télécharger des fichiers. Le code JavaScript est aussi simple que le code suivant: code. Cependant, la nouvelle version ne fonctionne pas dans Internet Explorer.

$('#file_upload').uploadify({
    'swf': '/public/js/uploadify.swf',
    'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
    'cancelImg': '/public/images/uploadify-cancel.png',
    'multi': true,
    'onQueueComplete': function (queueData) {
        // ...
    },
    'onUploadStart': function (file) {
        // ...
    }
});

J'ai fait beaucoup de recherches et je suis arrivé à une autre solution pour télécharger des fichiers sans aucun plugin et uniquement avec ajax. La solution est la suivante:

$(document).ready(function () {
    $('#btn_Upload').live('click', AjaxFileUpload);
});

function AjaxFileUpload() {
    var fileInput = document.getElementById("#Uploader");
    var file = fileInput.files[0];
    var fd = new FormData();
    fd.append("files", file);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'Uploader.ashx');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
             alert('success');
        }
        else if (uploadResult == 'success')
            alert('error');
    };
    xhr.send(fd);
}
farnoush resa
la source
2
Uploadify est mort depuis des années. Plus supporté ni maintenu.
Ray Nicholus
24

Voici juste une autre solution pour télécharger un fichier ( sans aucun plugin )

Utilisation de Javascripts simples et AJAX (avec barre de progression)

Partie HTML

<form id="upload_form" enctype="multipart/form-data" method="post">
    <input type="file" name="file1" id="file1"><br>
    <input type="button" value="Upload File" onclick="uploadFile()">
    <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
    <h3 id="status"></h3>
    <p id="loaded_n_total"></p>
</form>

Pièce JS

function _(el){
    return document.getElementById(el);
}
function uploadFile(){
    var file = _("file1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("file1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
    _("status").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
    _("status").innerHTML = "Upload Aborted";
}

Partie PHP

<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
}
if(move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
    echo "$fileName upload is complete";
} else {
    echo "move_uploaded_file function failed";
}
?>

Voici l'application EXEMPLE

Siddhartha Chowdhury
la source
19
var formData=new FormData();
formData.append("fieldname","value");
formData.append("image",$('[name="filename"]')[0].files[0]);

$.ajax({
    url:"page.php",
    data:formData,
    type: 'POST',
    dataType:"JSON",
    cache: false,
    contentType: false,
    processData: false,
    success:function(data){ }
});

Vous pouvez utiliser les données du formulaire pour publier toutes vos valeurs, y compris les images.

Vivek Aasaithambi
la source
6
Remarque: cache: falseest redondant sur une POSTdemande car POST ne met jamais en cache.
Fin du codage
@Vivek Aasaithambi, j'ai eu cette erreur:TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
candlejack
15

Pour télécharger un fichier de manière asynchrone avec Jquery, procédez comme suit:

étape 1 Dans votre projet, ouvrez le gestionnaire Nuget et ajoutez un package (jquery fileupload (il vous suffit de l'écrire dans la zone de recherche, il apparaîtra et l'installera.)) URL: https://github.com/blueimp/jQuery-File- Télécharger

étape 2 Ajoutez les scripts ci-dessous dans les fichiers HTML, qui sont déjà ajoutés au projet en exécutant le package ci-dessus:

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

étape 3 Écrivez le contrôle de téléchargement de fichier selon le code ci-dessous:

<input id="upload" name="upload" type="file" />

étape 4, écrivez une méthode js comme uploadFile comme ci-dessous:

 function uploadFile(element) {

            $(element).fileupload({

                dataType: 'json',
                url: '../DocumentUpload/upload',
                autoUpload: true,
                add: function (e, data) {           
                  // write code for implementing, while selecting a file. 
                  // data represents the file data. 
                  //below code triggers the action in mvc controller
                  data.formData =
                                    {
                                     files: data.files[0]
                                    };
                  data.submit();
                },
                done: function (e, data) {          
                   // after file uploaded
                },
                progress: function (e, data) {

                   // progress
                },
                fail: function (e, data) {

                   //fail operation
                },
                stop: function () {

                  code for cancel operation
                }
            });

        };

Étape 5 Dans le téléchargement de fichier d'élément d'appel de fonction prêt pour lancer le processus comme ci-dessous:

$(document).ready(function()
{
    uploadFile($('#upload'));

});

étape 6 Écrivez le contrôleur MVC et l'action comme ci-dessous:

public class DocumentUploadController : Controller
    {       

        [System.Web.Mvc.HttpPost]
        public JsonResult upload(ICollection<HttpPostedFileBase> files)
        {
            bool result = false;

            if (files != null || files.Count > 0)
            {
                try
                {
                    foreach (HttpPostedFileBase file in files)
                    {
                        if (file.ContentLength == 0)
                            throw new Exception("Zero length file!");                       
                        else 
                            //code for saving a file

                    }
                }
                catch (Exception)
                {
                    result = false;
                }
            }


            return new JsonResult()
                {
                    Data=result
                };


        }

    }
cendré
la source
14

Une approche moderne sans Jquery consiste à utiliser l' objet FileList que vous récupérez <input type="file">lorsque l'utilisateur sélectionne un ou plusieurs fichiers, puis à utiliser Fetch pour publier la FileList enroulée autour d'un objet FormData .

// The input DOM element // <input type="file">
const inputElement = document.querySelector('input[type=file]');

// Listen for a file submit from user
inputElement.addEventListener('change', () => {
    const data = new FormData();
    data.append('file', inputElement.files[0]);
    data.append('imageName', 'flower');

    // You can then post it to your server.
    // Fetch can accept an object of type FormData on its  body
    fetch('/uploadImage', {
        method: 'POST',
        body: data
    });
});
Alister
la source
Apparemment non pris en charge sur IE
Marco Demaio
11

Vous pouvez voir une solution résolu avec un travail démo ici qui vous permet de visualiser et de soumettre des fichiers de formulaire au serveur. Pour votre cas, vous devez utiliser Ajax pour faciliter le téléchargement de fichiers sur le serveur:

<from action="" id="formContent" method="post" enctype="multipart/form-data">
    <span>File</span>
    <input type="file" id="file" name="file" size="10"/>
    <input id="uploadbutton" type="button" value="Upload"/>
</form>

Les données soumises sont un formulaire. Sur votre jQuery, utilisez une fonction d'envoi de formulaire au lieu d'un clic de bouton pour soumettre le fichier de formulaire comme indiqué ci-dessous.

$(document).ready(function () {
   $("#formContent").submit(function(e){

     e.preventDefault();
     var formdata = new FormData(this);

 $.ajax({
     url: "ajax_upload_image.php",
     type: "POST",
     data: formdata,
     mimeTypes:"multipart/form-data",
     contentType: false,
     cache: false,
     processData: false,
     success: function(){

     alert("successfully submitted");

     });
   });
});

Afficher plus de détails

Daniel Nyamasyo
la source
11

Exemple: si vous utilisez jQuery, vous pouvez facilement télécharger un fichier. Ceci est un plugin jQuery petit et puissant, http://jquery.malsup.com/form/ .

Exemple

var $bar   = $('.ProgressBar');
$('.Form').ajaxForm({
  dataType: 'json',

  beforeSend: function(xhr) {
    var percentVal = '0%';
    $bar.width(percentVal);
  },

  uploadProgress: function(event, position, total, percentComplete) {
    var percentVal = percentComplete + '%';
    $bar.width(percentVal)
  },

  success: function(response) {
    // Response
  }
});

J'espère que ce serait utile

MEAbid
la source
10

Vous pouvez utiliser

$(function() {
    $("#file_upload_1").uploadify({
        height        : 30,
        swf           : '/uploadify/uploadify.swf',
        uploader      : '/uploadify/uploadify.php',
        width         : 120
    });
});

Démo

Amit
la source
9

Convertissez le fichier en base64 à l'aide de readAsDataURL () de HTML5 ou d' un encodeur base64 . Jouez ici

var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);

Puis récupérer:

window.open("data:application/octet-stream;base64," + base64);
tnt-rox
la source
9

Vous pouvez transmettre des paramètres supplémentaires avec le nom du fichier lors de la réalisation d'un téléchargement asynchrone à l'aide de XMLHttpRequest (sans dépendance flash et iframe). Ajoutez la valeur de paramètre supplémentaire avec FormData et envoyez la demande de téléchargement.


var formData = new FormData();
formData.append('parameter1', 'value1');
formData.append('parameter2', 'value2'); 
formData.append('file', $('input[type=file]')[0].files[0]);

$.ajax({
    url: 'post back url',
    data: formData,
// other attributes of AJAX
});

En outre, le téléchargement de fichiers d'interface utilisateur JavaScript Syncfusion fournit une solution pour ce scénario en utilisant simplement un argument d'événement. vous pouvez trouver la documentation ici et plus de détails sur ce contrôle ici entrez la description du lien ici

Karthik Ravichandran
la source
8

Recherchez Gestion du processus de téléchargement d'un fichier, de manière asynchrone ici: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

Échantillon du lien

<?php
if (isset($_FILES['myFile'])) {
    // Example:
    move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>dnd binary upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function sendFile(file) {
            var uri = "/index.php";
            var xhr = new XMLHttpRequest();
            var fd = new FormData();

            xhr.open("POST", uri, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // Handle response.
                    alert(xhr.responseText); // handle response.
                }
            };
            fd.append('myFile', file);
            // Initiate a multipart/form-data upload
            xhr.send(fd);
        }

        window.onload = function() {
            var dropzone = document.getElementById("dropzone");
            dropzone.ondragover = dropzone.ondragenter = function(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            dropzone.ondrop = function(event) {
                event.stopPropagation();
                event.preventDefault();

                var filesArray = event.dataTransfer.files;
                for (var i=0; i<filesArray.length; i++) {
                    sendFile(filesArray[i]);
                }
            }
        }
    </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
    </div>
</body>
</html>
Allende
la source
7

C'est ma solution.

<form enctype="multipart/form-data">    

    <div class="form-group">
        <label class="control-label col-md-2" for="apta_Description">Description</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
        </div>
    </div>

    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

et les js

<script>

    $(':button').click(function () {
        var formData = new FormData($('form')[0]);
        $.ajax({
            url: '@Url.Action("Save", "Home")',  
            type: 'POST',                
            success: completeHandler,
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });
    });    

    function completeHandler() {
        alert(":)");
    }    
</script>

Manette

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    [...]
}
Erick Langford Xenes
la source
2
Vous semblez avoir mélangé une sorte de cadre dans votre réponse. Vous devez, à tout le moins, mentionner pour quel cadre votre réponse est utilisable. Mieux encore, supprimez tous les trucs du framework et ne présentez qu'une réponse à la question posée.
Zero3
2
donc il y a en fait un framework mvc appelé "mvc"? et il utilise la syntaxe csharpish? c'est cruel.
nonchip
6

En utilisant HTML5 et JavaScript , le téléchargement asynchrone est assez facile, je crée la logique de téléchargement avec votre code html, cela ne fonctionne pas pleinement car il a besoin de l'API, mais démontrez comment cela fonctionne, si vous avez le point de terminaison appelé /uploaddepuis la racine de votre site Web, ce code devrait fonctionner pour vous:

const asyncFileUpload = () => {
  const fileInput = document.getElementById("file");
  const file = fileInput.files[0];
  const uri = "/upload";
  const xhr = new XMLHttpRequest();
  xhr.upload.onprogress = e => {
    const percentage = e.loaded / e.total;
    console.log(percentage);
  };
  xhr.onreadystatechange = e => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log("file uploaded");
    }
  };
  xhr.open("POST", uri, true);
  xhr.setRequestHeader("X-FileName", file.name);
  xhr.send(file);
}
<form>
  <span>File</span>
  <input type="file" id="file" name="file" size="10" />
  <input onclick="asyncFileUpload()" id="upload" type="button" value="Upload" />
</form>

Également quelques informations supplémentaires sur XMLHttpReques:

L'objet XMLHttpRequest

Tous les navigateurs modernes prennent en charge l'objet XMLHttpRequest. L'objet XMLHttpRequest peut être utilisé pour échanger des données avec un serveur Web en arrière-plan. Cela signifie qu'il est possible de mettre à jour des parties d'une page Web, sans recharger la page entière.


Créer un objet XMLHttpRequest

Tous les navigateurs modernes (Chrome, Firefox, IE7 +, Edge, Safari, Opera) ont un objet XMLHttpRequest intégré.

Syntaxe de création d'un objet XMLHttpRequest:

variable = new XMLHttpRequest ();


Accès à travers les domaines

Pour des raisons de sécurité, les navigateurs modernes ne permettent pas l'accès à travers les domaines.

Cela signifie que la page Web et le fichier XML qu'elle essaie de charger doivent être situés sur le même serveur.

Les exemples sur W3Schools tous les fichiers XML ouverts situés sur le domaine W3Schools.

Si vous souhaitez utiliser l'exemple ci-dessus sur l'une de vos propres pages Web, les fichiers XML que vous chargez doivent se trouver sur votre propre serveur.

Pour plus de détails, vous pouvez continuer à lire ici ...

Alireza
la source
5

Vous pouvez utiliser l' API Fetch plus récente par JavaScript. Comme ça:

function uploadButtonCLicked(){
    var input = document.querySelector('input[type="file"]')

    fetch('/url', {
      method: 'POST',
      body: input.files[0]
    }).then(res => res.json())   // you can do something with response
      .catch(error => console.error('Error:', error))
      .then(response => console.log('Success:', response));
}                               

Avantage: Fetch API est nativement pris en charge par tous les navigateurs modernes, vous n'avez donc rien à importer. Notez également que fetch () renvoie une promesse qui est ensuite gérée en utilisant de .then(..code to handle response..)manière asynchrone.

Blackeard
la source
4

Vous pouvez faire des téléchargements de fichiers multiples asynchrones en utilisant JavaScript ou jQuery et cela sans utiliser de plugin. Vous pouvez également afficher la progression en temps réel du téléchargement de fichiers dans le contrôle de progression. J'ai rencontré 2 liens sympas -

  1. ASP.NET Web Forms, fonction de téléchargement de fichiers multiples avec barre de progression
  2. Téléchargement de fichiers multiples basé sur ASP.NET MVC dans jQuery

Le langage côté serveur est C # mais vous pouvez faire quelques modifications pour le faire fonctionner avec un autre langage comme PHP.

Téléchargement de fichier ASP.NET Core MVC:

Dans le contrôle View create file upload en html:

<form method="post" asp-action="Add" enctype="multipart/form-data">
    <input type="file" multiple name="mediaUpload" />
    <button type="submit">Submit</button>
</form>

Créez maintenant une méthode d'action dans votre contrôleur:

[HttpPost]
public async Task<IActionResult> Add(IFormFile[] mediaUpload)
{
    //looping through all the files
    foreach (IFormFile file in mediaUpload)
    {
        //saving the files
        string path = Path.Combine(hostingEnvironment.WebRootPath, "some-folder-path"); 
        using (var stream = new FileStream(path, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }
    }
}

La variable hostingEnvironment est de type IHostingEnvironment qui peut être injectée dans le contrôleur à l'aide de l'injection de dépendance, comme:

private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
    hostingEnvironment = environment;
}
Joe Clinton
la source
Pourriez-vous inclure l'essence de la solution dans votre réponse, car elle pourrait sinon devenir inutile si le site Web lié change ou se déconnecte.
Dima Kozhevin
4

Pour PHP, recherchez https://developer.hyvor.com/php/image-upload-ajax-php-mysql

HTML

<html>
<head>
    <title>Image Upload with AJAX, PHP and MYSQL</title>
</head>
<body>
<form onsubmit="submitForm(event);">
    <input type="file" name="image" id="image-selecter" accept="image/*">
    <input type="submit" name="submit" value="Upload Image">
</form>
<div id="uploading-text" style="display:none;">Uploading...</div>
<img id="preview">
</body>
</html>

JAVASCRIPT

var previewImage = document.getElementById("preview"),  
    uploadingText = document.getElementById("uploading-text");

function submitForm(event) {
    // prevent default form submission
    event.preventDefault();
    uploadImage();
}

function uploadImage() {
    var imageSelecter = document.getElementById("image-selecter"),
        file = imageSelecter.files[0];
    if (!file) 
        return alert("Please select a file");
    // clear the previous image
    previewImage.removeAttribute("src");
    // show uploading text
    uploadingText.style.display = "block";
    // create form data and append the file
    var formData = new FormData();
    formData.append("image", file);
    // do the ajax part
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            var json = JSON.parse(this.responseText);
            if (!json || json.status !== true) 
                return uploadError(json.error);

            showImage(json.url);
        }
    }
    ajax.open("POST", "upload.php", true);
    ajax.send(formData); // send the form data
}

PHP

<?php
$host = 'localhost';
$user = 'user';
$password = 'password';
$database = 'database';
$mysqli = new mysqli($host, $user, $password, $database);


 try {
    if (empty($_FILES['image'])) {
        throw new Exception('Image file is missing');
    }
    $image = $_FILES['image'];
    // check INI error
    if ($image['error'] !== 0) {
        if ($image['error'] === 1) 
            throw new Exception('Max upload size exceeded');

        throw new Exception('Image uploading error: INI Error');
    }
    // check if the file exists
    if (!file_exists($image['tmp_name']))
        throw new Exception('Image file is missing in the server');
    $maxFileSize = 2 * 10e6; // in bytes
    if ($image['size'] > $maxFileSize)
        throw new Exception('Max size limit exceeded'); 
    // check if uploaded file is an image
    $imageData = getimagesize($image['tmp_name']);
    if (!$imageData) 
        throw new Exception('Invalid image');
    $mimeType = $imageData['mime'];
    // validate mime type
    $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (!in_array($mimeType, $allowedMimeTypes)) 
        throw new Exception('Only JPEG, PNG and GIFs are allowed');

    // nice! it's a valid image
    // get file extension (ex: jpg, png) not (.jpg)
    $fileExtention = strtolower(pathinfo($image['name'] ,PATHINFO_EXTENSION));
    // create random name for your image
    $fileName = round(microtime(true)) . mt_rand() . '.' . $fileExtention; // anyfilename.jpg
    // Create the path starting from DOCUMENT ROOT of your website
    $path = '/examples/image-upload/images/' . $fileName;
    // file path in the computer - where to save it 
    $destination = $_SERVER['DOCUMENT_ROOT'] . $path;

    if (!move_uploaded_file($image['tmp_name'], $destination))
        throw new Exception('Error in moving the uploaded file');

    // create the url
    $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
    $domain = $protocol . $_SERVER['SERVER_NAME'];
    $url = $domain . $path;
    $stmt = $mysqli -> prepare('INSERT INTO image_uploads (url) VALUES (?)');
    if (
        $stmt &&
        $stmt -> bind_param('s', $url) &&
        $stmt -> execute()
    ) {
        exit(
            json_encode(
                array(
                    'status' => true,
                    'url' => $url
                )
            )
        );
    } else 
        throw new Exception('Error in saving into the database');

} catch (Exception $e) {
    exit(json_encode(
        array (
            'status' => false,
            'error' => $e -> getMessage()
        )
    ));
}
Supun Kavinda
la source
4

Vous pouvez également envisager d'utiliser quelque chose comme https://uppy.io .

Il télécharge les fichiers sans s'éloigner de la page et offre quelques bonus comme le glisser-déposer, la reprise des téléchargements en cas de plantage du navigateur / des réseaux instables et l'importation par exemple d'Instagram. C'est open source et ne repose pas sur jQuery / React / Angular / Vue, mais peut être utilisé avec. Avertissement: en tant que créateur, je suis partial;)

kvz
la source
Le lien ci-dessus est mort. Voici le github: github.com/transloadit/uppy
Chris Charles
uppy.io est-ce que les pages CloudFlare + GitHub sont sauvegardées, et pour moi? Toujours aussi utile d'avoir le lien direct repo :)
kvz