Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

8juil/0842

Flex FileReference – Upload de fichiers avec la méthode upload() et browse()

La méthode FileReference.browse() vous permet d'autoriser l'utilisateur à parcourir ses fichiers pour en sélectionner un à uploader. Vous pouvez aussi utiliser FileReference.browse() pour permettre à l'utilisateur de sélectionner plusieurs fichiers à la fois.

FileReference.browse() permet de choisir un seul fichier alors que FileReferenceList.browse() permet d'en choisir plusieurs

Dans les deux cas (FileReference et FileReferenceList), la fenêtre permettant de parcourir le système de fichiers a deux boutons permettant à l'utilisateur de fermer la boîte de dialogue: Ouvrir et Annuler. L'objet FileReference ou FileReferenceList lancent des événements différents suivant quel bouton est cliqué par l'utilisateur. Si l'utilisateur clique sur le bouton Annuler (Cancel), il lance un événement cancel (Event.CANCEL). Si l'utilisateur clique sur le bouton Open, il lance un événement select (Event.SELECT).

Quand l'utilisateur a séléctionné un ou plusieurs fichiers (l'événement "select" a été dispatché), vous pouvez commencer l'upload du ou des fichiers en utilisant la méthode upload(). Cette méthode requiert que vous lui passiez un objet URLRequest spécifiant l'URL depuis vers uploader le fichier:

var fileReference:FileReference = new FileReference();
fileReference.upload(new URLRequest("upload.php"));

Si vous utilisez un objet FileReferenceList, vous devez appeler la méthode upload() à chaque instance stockée dans la propriété fileList:

var request:URLRequest = new URLRequest("upload.php");
for (var i:int = 0;i < fileReferenceList.fileList.length; i++){
	fileReferenceList.fileList[i].upload(request);
}

Pour recevoir des fichiers uploadés depuis Flash Player, vous devez avoir un script serveur qui peut recevoir ces requêtes. Quand une requête de ce type est faîte à un script côté serveur, elle est faite exactement de la même manière que si vous aviez utilisé qu'un requête standard depuis un formulaire HTML qui soumet un requête avec un champ contenant l'adresse du fichier: en utilisant POST et un type de contenu multipart/form-data.

Articles similaires

Commentaires (42) Trackbacks (1)
  1. En HTML/PHP, on spécifie un nom au champ input, afin de pouvoir désigner le fichier par $_FILES[nom_de_l_input].

    Comment fait-on ?

  2. Salut,
    Pour le script PHP, tu peux utiliser ce script existant:
    http://weblog.cahlan.com/files/php_fileuploads.html
    L'upload se passe en faisant _refUploadFile.upload(request, "file", false);
    et tu peux accéder à ton fichier en utilisant $_FILES['file']['name'];
    Pour un exemple complet d'upload Flex + PHP, tu peux consulter:
    http://weblog.cahlan.com/files/file_uploads/FileUpload.html

  3. Super ! sympa pour le multi-upload.
    En fait le nom de l'input est le 2nd paramètre que l'on passe à la méthode upload() du FileReference.

    Merci

  4. Salut,

    Je n'arrive pas à retrouver le script php dans les sources.
    Et avec le premier lien que tu as donné, je n'arrive pas à uploader (pourtant flex me dit que c'est bon, mais je ne trouve pas le fichier sur le serveur).

    Merci d'avance

  5. Salut,
    Vérifie si tu as bien les droits d'écriture (777) sur le dossier de destination sinon l'upload ne se fera pas.

    Fabien

  6. Merci pour ces tutoriaux très pratiques!

  7. Bonjour,
    j'ai beau testé cet exemple fnicollet, j'ai tout configuré dans l'appli Flex et dans le script PHP, j'ai fais mon chmod 777 sur le répertoire myFileDir, mais les fichiers uploadés n'apparaissent pas. L'application dit que c'est bon, mais rien n'apparait. J'ai testé sur un autre serveur, c'est pareil, et avec d'autres exemples d'uploading, ca ne fonctionne pas. Pourtant quand je fais un script php pour un uploading à partir d'un formulaire, çà fonctionne parfaitement.
    Je m'arrache les cheveux depuis 2 jours (déjà que j'en ai presque plus …), aurais-tu une idée s'il te plait ?

  8. Salut Stéphane,
    Je n'ai pas vraiment d'idée à te proposer, il faudrait voir s'il y a une erreur au niveau du traitement PHP. Si tu utilises ce script:
    http://weblog.cahlan.com/files/php_fileuploads.html
    Et que tu regardes le retour XML, obtiens-tu des erreurs ?

    Fabien

  9. Meme problème, et j'arrive pas à trouver de solution :(

  10. Bon finalement j'ai remplacé wamp par xampp et ca marche (en placant mon upload.php sur un mon serveur free, ca m'a mis la puce à l'oreille). Donc je suppose que c'est un ptit truc dans le php.ini mais lequel???? Si qqn a la réponse je suis très intéressé (par curiosité) !

  11. Bonjour a tous,

    j'essaie d'utiliser l'exemple d'upload et ça marche bien sauf que j'arrive pas a retrouver les fichiers uploadés

  12. Après le lancement de la méthode FileRefence.Upload(URL), il ya l'erreur suivante:
    Error #2039: Protocole URL distant non valide. Le protocole URL distant doit être HTTP ou HTTPS.
    C'est dû à quoi ? Merci.

  13. J'ai trouvé la raison de cette erreur, en fait c'est dû à ceci:
    Avec les testes dans flex builder: celui-ci utilise le protocole File:// (Affiché au début de chaque adresse dans le navigateur).
    En effectuant les testes en dehors de flex builder (c-a-d en lançant le le localhost de wampserver2 par exemple et en navigant au répertoire bindebug, le problème sera résolu(parceque ici le protocole utilisé est du http).

    Bon maintenant, j'ai rencontré un ptit bug, l'upload se fait normalement en m'affichant que le fichier à bien été uploadé dans le répertoire cible, mais en naviguant vers ce répertoire, Nul trace du fichier, ?????, Quelqu'un peut-il m'aider, Merci.

  14. Salut

    Idem, l'appli dit que tout est ok mais au final j'ai rien dans mon repertoire de destination???

    Quelqu'un a trouvé ? J'ai mis en 777 le rep de destination.

    Merci d'avance

  15. On a eu le même problème, et la solution a été trouvée : dans php.ini, il faut changer la ligne post_max_size (et le upload_max_filesize si nécessaire), qui est par défaut à 8M, donc les fichiers qui dépassent sont dit uploadés alors qu'ils ne le sont pas.
    En espérant que c'était bien le même problème que vous aviez. =)

  16. Merci pour cette précision :)

    Fabien

  17. Bonjour TLM,
    je te remercie pour ce très bon tuto
    et là j'ai besoin de savoir comment le faire avec un back End Rails

    Cordialement,

  18. Bonjour à tous, merci pour ces tutos,
    auriez vous une idée concernant l'utilisation de l'upload vers une application Struts (servlet Java)?
    Merci.
    Cédric

  19. Et bien je suppose que ca se passe exactement comme lorsque l'on passe par un upload HTML: pour un tuto sur l'upload HTML, voici un bon tuto:
    http://www.roseindia.net/struts/strutsfileuploadandsave.shtml
    Si tu arrives à tout faire fonctionner, tu peux poster un tutorial sur flex-tutorial !
    http://www.flex-tutorial.fr/publiez-vos-tutoriaux-flex-air-sur-flex-tutorial/

    Merci!
    Fabien

  20. Salut,
    Je cherche à uploader (appli AIR) une arborescence précise du poste local vers un serveur.
    Pour cela je liste d'abord les dossiers et sous dossiers afin de trouver le fichier de cette façon

    MXML:
    1. private var fileList:Array = new Array();
    2.  
    3. private function uploadFile(path:String):void{
    4. //test existence arbo :
    5. var arrLocal:Array = new Array();
    6. var firstFile:File = new File(path);
    7. //récupère sous dossier
    8. arrLocal = firstFile.getDirectoryListing();
    9.     for (var f:uint = 0; f &lt;arrLocal.length; f++) {
    10.              if (arrLocal[f].isDirectory) {
    11.                  if (arrLocal[f].name !="." &amp;&amp; arrLocal[f].name !="..") {
    12.                         //c'est un repertoire
    13.                         uploadFile(arrLocal[f].nativePath);
    14.  
    15.                     }
    16.                 }
    17.             else {
    18.                     //c'est un fichier
    19.                     fileList.push(arrLocal[f].nativePath);
    20.                     }
    21.             }
    22. }

    Le problème c'est que je dois uploader le fichier en conservant cette arborescence. Je souhaite "déclencher" mon script ASP uniquement lorsque que le parcours de l'arborescence est terminée.
    Est-ce possible ?

    Merci pour ton aide et encore merci pour cette bible que représente ton site
    PS: désolé si c'est HS

    Nico

  21. Salut,
    Si j'ai bien compris ce que tu souhaites faire, tu veux récupérer tous les "nativePath" des fichiers de ton arborescence et les envoyer à ton script ASP ensuite. Tu ne peux donc pas appeler uploadFile() dans tes boucles. Il suffit que tu déclares un Array avant (var nativePaths:Array = [];) et quand tu croise un nativePath, tu fais nativePaths.push(arrLocal[f].nativePath);
    Après ta boucle, tu aura donc un tableau de chemin que tu pourras envoyer à ton script ASP.

    Fabien
    PS: au lieu de faire une boucle for à l'ancienne, fait plutôt une boucle for each typée:
    for each (var currentFile:File in firstFile.getDirectoryListing()){
    if (currentFile.isDirectory){
    // suite...
    }
    }
    C'est plus propre, plus rapide et beaucoup mieux :)

  22. Merci pour les conseils pour le for each.
    Par contre il me semblait que mon array FileList contenait déjà tous mes nativepath.

    MXML:
    1. else {
    2.                     //c'est un fichier
    3.                     fileList.push(arrLocal[f].nativePath);
    4.                     }
    5.             }
    6. }

    Mon problème est que je n'arrive pas a détecter la fin de ma fonction pour envoyer mon array complètement. Je fais une erreur ?

  23. Je ne comprend pas, la fin de quelle fonction ? uploadFile?

  24. c'est vrai que mon explication est plutôt confuse !
    Le nom de ma fonction pour l'exemple prête plutôt à confusion également. Désolé.
    Je récapitule donc :
    J'appelle cette function(nommé ici uploadFile) afin de parcourir l'arborescence d'un dossier afin de l'uploader en conservant l'arborescence sur le serveur.
    Je pense récupérer tous les chemins dans mon array fileList que je traiterai par la suite avec mon script ASP pour créer si nécessaire mon arborescence (ou simplement mettre à jour le fichier final si l'arborescence existe déjà
    Puis par la suite j'uploaderai les différents fichiers avec la méthode upload de AIr.
    Mon soucis est que je ne sais pas comment m'y prendre pour que mon script ASP soit appelé à la fin de ma function (la mal nommée UploadFile) car si je met à trace("fini") après la boucle For celui-ci apparait plusieurs fois.

    Je doit certainement mal m'y prendre et passer à coté d'une évidence.

    Merci en tout cas pour ton aide

  25. Ok, donc en fait, ta fonction uploadFile() est une fonction récursive, c'est ce qu'il me semblait. Ce qu'il faut alors c'est que cette fonction uploadFile renvoie (return) un Array de nativePath.
    Si la fonction uploadFile() rencontre un fichier, elle ajoute la nativePath au tableau qu'il va retourner.
    Si la fonction uploadFile() rencontre un dossier, elle va appeler uploadFile sur le path. Cet appel va retourner un tableau de nativePath qui va être ajouté au retour de la fonction (une récursion tout bête).
    Le premier appel à uploadFile() va donc te retourner un tableau contenant l'ensemble des nativePath que tu pourra balancer à ton service ASP.

    Fabien

  26. Merci.
    Je n'avais pas penser au return !
    Je dois avoir besoin de repos après mes vacances.
    Merci je récupère sans pb mon Array !!

    A ++
    Nico

  27. Salut !
    Est-il possible d'utiliser la méthode filereference.UPLOAD sans passer par un FileReference.BROWSE ?
    En effet je dispose (Cf. ci-dessus) d'un array contenant les nativePath de ces fichiers et je ne souhaite pas d'autres actions de l'utilisateurs.

    Merci.

    Nico.

  28. J'ai posé ma question trop vite désolé !

    Il ne faut pas utiliser dans mon cas FileReference mais directement FIle.
    Je pensais que la méthode upload était dispo uniquement avec filereference

    Désolé.

  29. Salut,
    Pour ma part j'ai un souci avec la méthode upload de filereference, dès que je met un fichers supérieur à 40 Mo, le player freeze pendant quelques seconde avant de commencer l'upload. Bien sur plus le fichier est gros plus le freeze est long. quelqu'un à t'il déja eu ce problème ?

    Ensuite j'ai aussi un probleme coté serveur, je souhaiterais verifier un token que j'envois avec mon fichier(en header) avant que celui ci ne commence de le charger. Le token se transmet bien helas je n'arrive pas à trouver de solutions qui me permetrais de lire le contenu du header avant de telecharger tout le fichier. J'utilise une page jsp pour l'upload, mais siq quelqu'un à une solution dans n'importe quel language ca m'interesse aussi :)

    Et allez, 1 petit dernier pour la route, comme les solutions avec l'upload du filereference ne marchait pas j'ai voulu mettre en place une autre technique d'upload. Je souhaitais pouvoir envoyer le fichier sous la forme de bytearray via une solution de type remoting. ca marche tres bien mais si le fichier fais 500 Mo je suis obligé de faire monter un ByteArray de 500Mo en mémoire.. donc pas bon. Avec Air il y a la classe fileStream qui me permettrais de lire mon fichier par morceau de quelques mega et de les envoyer en plusieurs fois, mais helas cette methode n'est pas implémenté en dehors de Air. Auriez vous aussi une idée là-dessus ?

    Fred

  30. Et comment peut-on faire pour personnaliser le nom du répertoire de destination du fichier uploadé à partir de flash ?

    1) La fonction .upload() ne permet que de mettre l'URL du script php.
    2) l'objet FileReference ne comprend pas lorsque j'essaye de lui ajouter une propriété que je tente de récupérer côté php…

    des idées ou je me plante dans mon raisonnement ?

    Merci d'avance.

    Ben

  31. Salut,
    en fait, tu cherches à faire transiter une variable de flash vers ton script PHP au moment de l'upload si j'ai bien compris. As-tu essayé de l'envoyer en GET sur l'URL de ton fichier PHP pour le récupérer au moment de l'upload?

    Fabien

  32. yep,
    très exactement, j'ai tenter de rajouter ma variable comme suit dans la requète de l'upload();
    ex :
    monFileReference.upload("adressedemonscriptephp.php?chemindudossier="+varCheminDuDossier+"");

    puis je tente de la récupérer dans php avec :
    $dosier=$chemindudossier;

    En faisant un :
    return $dossier ;
    la variable est vide.

    Mais je m'y suis peut-être mal pris…
    C'est ça dans l'idée ?

  33. désolé mon post est un peu sale, je refais :
    "varCheminDuDossier" est ma variable dans flash
    ex dans flash :
    monFileReference.upload(new URLRequest("adressedemonscriptphp.php?chemindudossier="+varCheminDuDossier+""));

    puis je tente de la récupérer dans php avec :
    $dossier=$chemindudossier;

    En faisant un :
    return $dossier ;
    la variable est vide.

    Merci
    ben

  34. Hop, un petit tour dans la doc:
    http://livedocs.adobe.com/flex/3/html/help.html?content=17_Networking_and_communications_7.html
    You can pass additional variables to the upload script using either the POST or GET request method. To send additional POST variables to your upload script, you can use the following

    Actionscript:
    1. var fileRef:FileReference = new FileReference();
    2. fileRef.addEventListener(Event.SELECT, selectHandler);
    3. fileRef.addEventListener(Event.COMPLETE, completeHandler);
    4. fileRef.browse();
    5. function selectHandler(event:Event):void
    6. {
    7.     var params:URLVariables = new URLVariables();
    8.     params.date = new Date();
    9.     params.ssid = "94103-1394-2345";
    10.     var request:URLRequest = new URLRequest("http://www.yourdomain.com/FileReferenceUpload/fileupload.cfm");
    11.     request.method = URLRequestMethod.POST;
    12.     request.data = params;
    13.     fileRef.upload(request, "Custom1");
    14. }
    15. function completeHandler(event:Event):void
    16. {
    17.     trace("uploaded");
    18. }

  35. hum, hum, merci bien.
    J'avais été faire un tour dans la doc.
    J'avais vu ça aussi.

    Par contre je ne comprend pas comment l'utiliser pour mon propre code.

    Comment récupérer la variable coté php par exemple.
    Ou encore ou placer l'url du dossier varCheminDuDossier, evoquée plus haut.

    Toutefois merci bien, je vais me pencher sur les Get et Post dans un premier temps et voir si je comprend mieux tout ça.
    A +

    ben

  36. YAHOUUUUUUUU !!!!

    Merci beaucoup ! ça marche.

    Pour les lecteurs de ce post ayant la même question que moi :

    Passer la variable de flash à php :

    import flash.net.URLRequestMethod;
    import flash.net.URLVariables;

    var params:URLVariables = new URLVariables();
    //création de la ou les variables souhaités, ici "dossier" en tapant params.dossier
    params.dossier= "la valeur de votre variable dossier";
    requete.method = URLRequestMethod.POST;
    requete.data = params;
    monFileReference.upload(requete);

    Récupérer côté php :
    //ici "dossier" car c'est son intilulé déclaré dans flash
    $dossier = $_POST["dossier"];

    Merci, merci, merci Fabien, j'ai cru devenir fou.

  37. Merci pour ce tutoriel.Je voudrais savoir s'il est possible d'uploader différents types de fichiers(vidéo, images, etc.).Est-il de possible aussi de le faire avec de gros fichiers.
    Merci

  38. Bonjour,
    il est possible d'uploader n'importe quel fichier. Pour la taille, la bride se fait au niveau du script serveur (cgi, php, peu importe), pas au niveau de l'application Flash / Flex

    Fabien

  39. ok! Merci pour la réponse instantanée.

  40. Bonjour,

    J'aimerais si certains me le permettent qu'on reviennent sur l'upload de fichier a partir du FileReference et d'un scriptPhp.
    En ce qui me concerne ce n'est pas un proble de poids du fichier, car cux-ci sont inferieurs a 20KB.
    Mais apres avoir suivi le tutos a la lettre, je ne retrouve pas les fichers uploadés alors qu'en passant par un formulaire l'upload fonction.
    Besoin d'aide Merci .

  41. Re-Bonjour,

    Je viens de trouver un moyen de faire en sorte pour que sa marche. En faite si on force la valeur request a upload.
    Le deplacement de fichier se passe. donc dans le fichier Php ajouter la ligne
    $_REQUEST['action']= 'upload';
    avant le switch.
    Je sais que c'est pas le top mais au moins sa marche. surtout que le switch ne sert qu'a verifier si le fichier existe sur le serveur.
    ;)


Leave a comment

(required)