Gestion des transferts de fichiers avec AJAX/Axios

Ce guide explore les méthodes de transfert de fichiers asynchrones côté client en utilisant AJAX et Axios, ainsi que la configuration nécessaire côté serveur avec le framework SSM.

Accéder aux attributs HTML

Pour manipuler les attributs et le contenu des éléments HTML en JavaScript, l'accès direct par notation pointée est possible pour la plupart des attributs. Pour la clase d'un élément, utilisez className. Le contenu interne peut être modifié via innerHTML.

Récupérer le fichier sélectionné

Lorsqu'un utilisateur sélectionne un fichier via un élément input type="file", le fichier lui-même est accessible via la propriété files de l'élément. Pour un fichier unique :


var fichierUnique = document.getElementById('monFichier').files[0];
   

Pour gérer plusieurs fichiers, référez-vous à la documentation MDN concernant l'objet FileList.

Transformer les soumissions de formulaire synchrones en asynchrones

Côté Frontend

Utilisation d'AJAX (jQuery)

Pour convertir une soumission de formulaire classique en une requête AJAX, on peut utiliser jQuery. Il est essentiel de définir l'attribut enctype du formulaire à multipart/form-data pour permettre l'envoi de fichiers.


<form id="monFormulaire" enctype="multipart/form-data">
   <div>
       <label for="nomUtilisateur">Nom :</label>
       <input type="text" id="nomUtilisateur" name="nomUtilisateur">
   </div>
   <div>
       <label for="fichierUtilisateur">Fichier :</label>
       <input type="file" id="fichierUtilisateur" name="monFichier">
   </div>
   <button type="button" id="boutonSoumettre">Envoyer</button>
</form>

<script src="jquery-3.6.0.min.js"></script>
<script>
   $(document).ready(function() {
       $("#boutonSoumettre").click(function() {
           var donneesFormulaire = new FormData($("#monFormulaire")[0]);
           donneesFormulaire.append("description", "Fichier utilisateur"); // Ajout d'un champ supplémentaire

           $.ajax({
               url: "/api/upload", // L'URL de votre endpoint backend
               type: 'POST',
               data: donneesFormulaire,
               processData: false, // Empêche jQuery de traiter les données
               contentType: false, // Laisse le navigateur définir le Content-Type
               success: function(reponse) {
                   console.log("Succès :", reponse);
               },
               error: function(erreur) {
                   console.error("Erreur :", erreur);
               }
           });
       });
   });
</script>
   

Utilisation d'Axios

Axios est une alternative populaire pour effectuer des requêtes HTTP. Voici un exemple dans un contexte Vue.js :


<template>
   <div>
       <div>
           Nom : <input type="text" v-model="nom">
       </div>
       <div>
           Avatar : <input type="file" ref="avatarFichier">
       </div>
       <div @click="envoyerFichier">Sauvegarder</div>
   </div>
</template>

<script>
export default {
   data(){
       return {
           nom: ''
       }
   },
   methods:{
       envoyerFichier(){
           let donnees = new FormData();
           donnees.append('nomUtilisateur', this.nom);
           donnees.append('avatar', this.$refs.avatarFichier.files[0]);
           
           this.axios.post('/api/user/profile', donnees, {
               headers: {
                   'Content-Type': 'multipart/form-data'
               }
           }).then(reponse => {
               console.log("Réponse du serveur :", reponse.data);
           }).catch(erreur => {
               console.error("Erreur lors de l'envoi :", erreur);
           });
       }
   }
}
</script>
   

L'objet FormData est crucial pour la construction des données du formulaire, notamment lors de l'inclusion de fichiers. La configuration enctype="multipart/form-data" est nécessaire pour les formulaires envoyant des données binaires.

Côté Backend (Framework SSM)

1. Structure du Projet

Créez un répertoire pour stocker les fichiers téléchargés, par exemple, webapp/WEB-INF/uploads.

2. Dépendances Maven (pom.xml)

Ajoutez les bibliothèques nécessaires pour la gession des fichiers :


<dependency>
   <groupId>commons-io</groupId>
   <artifactId>commons-io</artifactId>
   <version>2.11.0</version>
</dependency>
<dependency>
   <groupId>commons-fileupload</groupId>
   <artifactId>commons-fileupload</artifactId>
   <version>1.5</version>
</dependency>
   

3. Configuraton Spring MVC (spring-mvc.xml)

Configurez un MultipartResolver pour gérer les requêtes de fichiers :


<!-- Configuration du MultipartResolver pour la gestion des uploads -->
<bean id="multipartResolver" 
     class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <property name="defaultEncoding" value="utf-8"/>
   <property name="maxUploadSize" value="10485760"/> <!-- Taille max en octets (ici 10MB) -->
</bean>
   

4. Contrôleur Spring

Créez un contrôleur pour recevoir et traiter le fichier :


package com.example.controller;

import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.UUID; // Pour générer des noms de fichiers uniques

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class FichierUploadController {

   @PostMapping("/uploadFichier")
   public ModelAndView gererUpload(
           @RequestParam("fichier") MultipartFile fichier, 
           HttpServletRequest requete) {

       ModelAndView mav = new ModelAndView("resultatUpload"); // Nom de la vue JSP

       if (fichier.isEmpty()) {
           mav.addObject("message", "Veuillez sélectionner un fichier à uploader.");
           return mav;
       }

       try {
           // Récupérer le nom original du fichier
           String nomOriginal = fichier.getOriginalFilename();
           // Obtenir l'extension du fichier
           String extension = "";
           int indicePoint = nomOriginal.lastIndexOf('.');
           if (indicePoint >= 0) {
               extension = nomOriginal.substring(indicePoint);
           }
           
           // Générer un nom de fichier unique basé sur UUID
           String nomFichierUnique = UUID.randomUUID().toString() + extension;

           // Déterminer le chemin de sauvegarde
           // Utilisation de Paths pour une meilleure gestion des chemins
           String cheminDossierUploads = requete.getServletContext().getRealPath("/WEB-INF/uploads");
           Path cheminFichier = Paths.get(cheminDossierUploads, nomFichierUnique);
           
           // Créer le répertoire s'il n'existe pas
           Files.createDirectories(cheminFichier.getParent());

           // Copier le fichier vers la destination
           try (InputStream is = fichier.getInputStream()) {
               Files.copy(is, cheminFichier, StandardCopyOption.REPLACE_EXISTING);
           }

           // Enregistrer les informations du fichier (ex: dans la base de données)
           // ...

           mav.addObject("message", "Le fichier '" + nomOriginal + "' a été uploadé avec succès !");
           mav.addObject("nomFichierSauvegarde", nomFichierUnique);

       } catch (Exception e) {
           e.printStackTrace();
           mav.addObject("message", "Erreur lors de l'upload du fichier.");
       }

       return mav;
   }
}
   

Points d'Attention

  1. Les fichiers uploadés sont sauvegardés sur le serveur (dans le répertoire configuré, par exemple, sous le répertoire d'application déployée sur Tomcat).
  2. Assurez-vous de la correspondance exacte des noms des paramètres entre le frontend (ex: name="monFichier") et le backend (ex: @RequestParam("fichier")). Une incohérence entraînera des erreurs.

Étiquettes: JavaScript AJAX axios Vue.js Spring MVC

Publié le 18 juin à 23h19