Multipart Upload dans le développement web : essence, structure et fonctionnement de multipart/form-data

Auteur : IT Sectr Publié le : 2026-03-10 Temps de lecture : 9 min

Multipart Upload est un mécanisme HTTP qui permet de transférer plusieurs parties hétérogènes de données dans une seule requête, y compris des champs de texte et des fichiers binaires. Chaque partie est séparée par une chaîne de limite unique et possède son propre en-tête Content-Type. Selon MDN Web Docs, 2025, multipart/form-data est le format standard pour télécharger des fichiers via des formulaires HTML et est largement utilisé dans les applications web et mobiles pour envoyer des images, des documents et d'autres fichiers au serveur.

Points clés

  • Multipart Upload — transfert de plusieurs parties de données dans une seule requête HTTP séparées par un boundary.
  • multipart/form-data — le type MIME standard pour télécharger des fichiers depuis des formulaires HTML et des applications mobiles.
  • Boundary — une chaîne unique qui sépare les parties d'une requête composée, générée automatiquement par les clients HTTP.
  • Chaque partie contient des en-têtes Content-Disposition et Content-Type décrivant le nom du champ et le type de fichier.
  • Multipart Upload est plus efficace que plusieurs requêtes — un POST remplace N appels séparés au serveur.

Qu'est-ce que Multipart Upload ?

Multipart Upload est une méthode de transfert de données via le protocole HTTP où le corps de la requête est constitué de plusieurs parties logiquement séparées. Chaque partie peut contenir des données d'un type différent : un champ de formulaire texte, un fichier binaire, un objet JSON ou une image. Toutes les parties sont regroupées dans une seule requête POST, éliminant le besoin d'envoyer N appels HTTP séparés. Multipart Upload est une partie essentielle des formulaires web et des API de téléchargement de fichiers.

Le format multipart a été défini dans la spécification RFC 2046 dans le cadre du standard MIME pour les messages électroniques, puis adapté pour HTTP dans la RFC 1867. Aujourd'hui, le développement web utilise presque exclusivement multipart/form-data — l'un des sous-types multipart conçus pour les formulaires contenant des fichiers. Les autres sous-types — multipart/mixed (pour les pièces jointes arbitraires) et multipart/byteranges (pour le téléchargement partiel de fichiers) — sont beaucoup moins utilisés.

La différence fondamentale entre multipart et application/x-www-form-urlencoded est que ce dernier encode toutes les données dans une chaîne compatible URI et ne prend pas en charge les fichiers binaires. Multipart/form-data, en revanche, transmet chaque fichier dans sa forme binaire d'origine sans encodage, ce qui est plus efficace et ne perd pas en précision. La taille de la requête avec multipart est toujours 5 à 15 % plus grande que la somme des tailles de fichiers en raison de la surcharge des en-têtes de parties et des limites.

Quand Multipart Upload est-il utilisé ?

Multipart Upload est utilisé partout où un téléchargement de fichier est nécessaire : avatars et photos de profil dans les réseaux sociaux, pièces jointes dans les messageries, documents dans les systèmes CRM, images de produits dans les boutiques en ligne. Dans les applications mobiles, Multipart Upload est utilisé pour envoyer des fichiers multimédias au serveur — photos de l'appareil photo, enregistrements vocaux, clips vidéo. Selon Cloudflare Research, environ 15 % de toutes les requêtes POST sur le web utilisent multipart/form-data.

Différence entre multipart et transfert par chunks

Multipart Upload et le transfert par chunks (Chunked Transfer) sont des mécanismes différents. Multipart divise une requête en parties significatives (champs et fichiers), tandis que le transfert par chunks divise un flux de données en fragments pour la transmission sans connaître la taille totale. Multipart peut être transmis à l'intérieur d'un transfert par chunks : le serveur envoie une réponse multipart par parties sans connaître sa taille complète. Ces mécanismes n'entrent pas en conflit et résolvent des problèmes différents à des niveaux différents.

Comment fonctionne multipart/form-data

Lorsqu'un navigateur soumet un formulaire avec l'attribut enctype="multipart/form-data", il construit le corps de la requête au format multipart. Chaque champ du formulaire devient un bloc séparé, séparé des autres par une chaîne de limite (boundary). La limite est générée automatiquement et constitue une séquence unique de caractères garantie de ne pas apparaître dans les données. Le client ajoute cette limite à l'en-tête Content-Type : multipart/form-data; boundary=----WebKitFormBoundaryX7K.

Chaque bloc commence par --boundary et contient des en-têtes Content-Disposition avec le nom du champ (name) et, pour les fichiers, le nom de fichier d'origine (filename). Après une ligne vide viennent les données du champ ou le contenu du fichier sous forme binaire. La requête se termine par la chaîne --boundary--. Le serveur analyse le flux reçu : il trouve d'abord la limite, puis extrait les en-têtes de chaque partie, détermine le type de données et les transmet au gestionnaire de formulaire ou au contrôleur API.

Selon IETF RFC 7578, multipart/form-data ne nécessite pas de spécifier un jeu de caractères pour chaque partie, car les champs de texte sont considérés en UTF-8 et les parties binaires contiennent des fichiers dans leur encodage d'origine. La taille d'une partie n'est pas limitée par le protocole — les limites sont définies au niveau du serveur : par exemple, dans Nginx via client_max_body_size, dans Spring Boot via spring.servlet.multipart.max-file-size.

Format du boundary et sa génération

Boundary est une chaîne unique qui ne doit pas apparaître dans les données transmises. Elle commence généralement par un préfixe (par exemple, ----WebKitFormBoundary ou ----Boundary) et contient des caractères aléatoires. Les navigateurs et les clients HTTP génèrent le boundary automatiquement. La longueur du boundary ne doit pas dépasser 70 caractères selon la RFC 2046. Chaque partie est séparée par la chaîne --boundary\r\n, et la fin de la requête est marquée par --boundary--\r\n.

Structure d'une requête multipart

Une requête multipart a une structure stricte définie par les normes MIME et HTTP. L'en-tête de la requête définit Content-Type : multipart/form-data avec un paramètre boundary. Le corps de la requête se compose d'une séquence de parties, chacune contenant ses propres en-têtes et corps. Les en-têtes de partie incluent Content-Disposition (obligatoire) et Content-Type (facultatif — pour les fichiers). Une ligne vide entre les en-têtes de la partie et ses données est obligatoire.

ÉlémentExempleObligatoire
Content-Typemultipart/form-data; boundary=---Bnd123Oui
Séparateur de partie---Bnd123Oui (avant chaque partie)
Content-Dispositionform-data; name="avatar"; filename="photo.jpg"Oui
Content-Type de partieimage/jpegPour les fichiers
Corps de partie[données binaires de l'image]Oui
Limite de fin---Bnd123--Oui (fin de requête)

Exemple de requête multipart

Considérons un exemple réel d'une requête multipart envoyant un champ texte et un fichier image. Le client forme l'en-tête Content-Type avec un boundary unique. Le corps de la requête contient séquentiellement tous les champs du formulaire. À la réception, le serveur analyse ces parties et donne au développeur accès à chaque champ comme un objet séparé. Cette approche permet de traiter des formulaires complexes avec des fichiers en un seul appel HTTP.

kotlin
import okhttp3.*
import java.io.File

fun uploadFile() {
    val client = OkHttpClient()
    val imageFile = File("/path/to/photo.jpg")

    val requestBody = MultipartBody.Builder()
        .setType(MediaType.parse("multipart/form-data"))
        .addFormDataPart("username", "john_doe")
        .addFormDataPart(
            "avatar", "photo.jpg",
            RequestBody.create(
                MediaType.parse("image/jpeg"), imageFile
            )
        )
        .build()

    val request = Request.Builder()
        .url("https://api.example.com/upload")
        .post(requestBody)
        .build()

    client.newCall(request).execute().use { response ->
        println("Téléchargé : ${response.isSuccessful}")
    }
}

Analyse d'une réponse multipart sur le serveur

Côté serveur, la requête multipart est analysée par le framework ou manuellement. Dans Spring Boot, l'annotation @RequestParam("avatar") MultipartFile file suffit, et le framework extrait automatiquement le fichier de la requête multipart. Dans Ktor sur Kotlin, on utilise receiveMultipart(), dans Express.js — le middleware multer. Le serveur accède à chaque champ du formulaire et à chaque fichier téléchargé indépendamment, enregistre le fichier sur le disque ou dans le stockage cloud et retourne une URL ou un identifiant au client.

Avantages du téléchargement multicomposant

Multipart Upload offre plusieurs avantages clés par rapport aux méthodes alternatives de transfert de données. Une requête au lieu de plusieurs — tous les champs du formulaire et les fichiers sont transmis en un seul appel HTTP, ce qui réduit la charge sur le réseau et le serveur. Il n'est pas nécessaire d'ouvrir N connexions pour télécharger N fichiers — tout est regroupé dans un seul POST. Ceci est particulièrement important pour les applications mobiles, où chaque connexion HTTP signifie latence et consommation de batterie.

Transfert binaire sans encodage — contrairement à application/x-www-form-urlencoded, où les données binaires sont encodées en base64 (augmentation de la taille de 33 %), multipart/form-data transmet les fichiers dans leur forme binaire d'origine. C'est plus efficace en taille et en vitesse. Pour les fichiers volumineux de plus de 10 Mo, la différence devient critique : une requête multipart sera 30 % plus petite qu'une requête encodée en URL avec le même fichier.

Structure arbitraire — multipart permet de combiner des champs de différents types dans n'importe quel ordre. Un formulaire peut contenir simultanément des champs de texte, plusieurs fichiers, des données JSON et des champs cachés. Chaque partie a son propre Content-Type, ce qui permet de mélanger des données texte et binaires. Pour comparaison : l'encodage base64 ajoute 33 % à la taille, tandis que multipart n'ajoute qu'environ 5 à 15 % pour les en-têtes de service.

Comparaison de multipart avec d'autres formats de transfert

Selon l'étude HTTP Archive, 2025, multipart/form-data est utilisé dans 94 % des cas de téléchargement de fichiers sur le web. Alternatives — base64 dans JSON (4 %) et transfert direct via WebSocket (2 %). JSON avec base64 est pratique pour les API où toutes les autres données sont également en JSON, mais inefficace pour les fichiers volumineux. WebSocket convient aux données en temps réel mais n'est pas supporté par toutes les infrastructures HTTP. Multipart reste la norme pour le téléchargement de fichiers grâce à sa simplicité et son efficacité.

Multipart Upload dans le développement mobile

Dans les applications mobiles, Multipart Upload est utilisé pour envoyer du contenu multimédia depuis les appareils des utilisateurs : photos de la galerie, prises de vue, enregistrements vocaux, fichiers de documents. Sur Android, l'approche standard est OkHttp avec MultipartBody.Builder, qui permet de former facilement des requêtes multipart. Retrofit supporte également multipart via les annotations @Multipart et @Part. Le développeur spécifie le type de données pour chaque partie, et le client HTTP génère automatiquement les en-têtes corrects.

Sur iOS, les mêmes tâches sont résolues avec URLSession avec un HTTPBodyStream personnalisé ou via Alamofire avec multipartFormData. Alamofire fournit une méthode pratique upload(multipartFormData:) pour envoyer des requêtes multipart. Sur les deux plateformes, il est important de prendre en compte la taille des fichiers téléchargés — pour les gros fichiers (plus de 10-20 Mo), il est recommandé d'utiliser le téléchargement en arrière-plan pour que l'application ne se termine pas lors de la minimisation. Sur Android, cela se fait via DownloadManager ou WorkManager ; sur iOS, via URLSession avec configuration d'arrière-plan.

Lors du téléchargement de fichiers dans les applications mobiles, l'état du réseau doit être pris en compte. Connectivity Manager sur Android aide à déterminer si le Wi-Fi ou les données mobiles sont disponibles et à choisir le moment optimal pour le téléchargement. Pour les fichiers volumineux comme les vidéos, il est recommandé de différer le téléchargement jusqu'à la connexion au Wi-Fi pour ne pas consommer les données mobiles de l'utilisateur. WorkManager sur Android permet de définir de telles contraintes via NetworkType.UNMETERED.

Optimisation du téléchargement : compression et redimensionnement

Avant d'envoyer un fichier via Multipart Upload, les applications mobiles compressent et redimensionnent souvent l'image. La compression JPEG avec une qualité de 85 % réduit la taille du fichier de 3 à 5 fois sans perte de qualité notable pour l'affichage à l'écran. Le redimensionnement de l'image à 1920 px sur le côté le plus long réduit encore la taille. Sur Android, on utilise Bitmap.compress() ; sur iOS, UIImageJPEGRepresentation avec un paramètre de compression de 0,85. Une telle optimisation accélère le téléchargement et économise les données mobiles.

Erreurs et limites de Multipart Upload

L'erreur la plus courante dans Multipart Upload est le dépassement de la limite de taille de requête sur le serveur. Par défaut, Nginx limite la taille du corps de la requête à 1 Mo (client_max_body_size), et Tomcat à 2 Mo (maxSwallowSize). Si le développeur n'augmente pas ces limites, le serveur retourne une erreur 413 Request Entity Too Large. La solution consiste à configurer explicitement la taille maximale de téléchargement sur le serveur et à afficher un avertissement sur le client si le fichier dépasse la taille autorisée.

Le deuxième problème est la gestion incorrecte des requêtes multipart lors du streaming du corps. Certains serveurs tentent de charger l'intégralité de la requête multipart en mémoire avant de l'analyser, ce qui entraîne une OutOfMemoryError pour les fichiers volumineux. Les serveurs modernes (Nginx, Spring Boot, Ktor) prennent en charge l'analyse en streaming de multipart, où chaque partie est traitée au fur et à mesure de son arrivée. Le développeur doit s'assurer que le serveur est configuré pour le traitement en streaming des requêtes multipart.

La troisième catégorie de problèmes concerne les délais d'attente lors du téléchargement de fichiers volumineux. Les clients HTTP ont des paramètres readTimeout et connectTimeout qui peuvent se déclencher lors de téléchargements longs de fichiers de plus de 50-100 Mo. La solution consiste à augmenter les délais d'attente pour les points de terminaison de téléchargement ou à utiliser le codage de transfert par chunks dans multipart. Sur les appareils mobiles, il est également important de gérer l'interruption du téléchargement et d'implémenter la reprise (resume) en cas de perte de connexion.

Sécurité de Multipart Upload

Le téléchargement de fichiers via multipart est l'un des points de terminaison les plus vulnérables d'une application web. Un attaquant peut télécharger un script exécutable en le renommant en image.jpg. Le serveur doit vérifier le type MIME du fichier téléchargé non pas par l'extension mais par le contenu (magic bytes), limiter les types autorisés et analyser les fichiers avec un antivirus. Il est recommandé de stocker les fichiers téléchargés en dehors du document-root du serveur web et de les servir via un contrôleur séparé avec vérification des droits d'accès.

Questions fréquentes

En quoi multipart/form-data diffère-t-il de application/x-www-form-urlencoded ?

multipart/form-data transmet chaque champ de formulaire comme un bloc séparé avec ses propres en-têtes et supporte les fichiers binaires sans encodage. application/x-www-form-urlencoded encode toutes les données dans une chaîne compatible URI (clé=valeur&clé2=valeur2) et ne supporte pas les fichiers directement — ils doivent être encodés en base64.

Quelle est la taille maximale de fichier pour Multipart Upload ?

Le protocole HTTP ne limite pas la taille d'une requête multipart, mais en pratique les limites sont définies par le serveur. Nginx par défaut limite à 1 Mo, Apache à 2 Mo, Spring Boot à 1 Mo. Pour télécharger des fichiers volumineux, configurez client_max_body_size (Nginx) ou spring.servlet.multipart.max-file-size (Spring Boot) à la valeur souhaitée — par exemple, 100 Mo.

Peut-on envoyer plusieurs fichiers dans une seule requête multipart ?

Oui, multipart/form-data supporte plusieurs fichiers dans une seule requête. Chaque fichier est transmis comme une partie séparée avec son propre Content-Disposition et Content-Type. Les formulaires HTML utilisent l'attribut multiple pour input type="file". Dans OkHttp, addFormDataPart est appelé pour chaque fichier ; dans Alamofire, append est appelé pour chaque fichier.

Pourquoi un boundary est-il nécessaire dans une requête multipart ?

Boundary est une chaîne unique qui sépare les parties d'une requête composée et permet au serveur de déterminer où une partie se termine et où une autre commence. Elle est générée par le client et spécifiée dans l'en-tête Content-Type. Sans boundary, le serveur ne peut pas analyser une requête multicomposant en champs et fichiers individuels.

Comment vérifier le type de fichier téléchargé sur le serveur ?

Ne vous fiez pas à l'extension du fichier ou au Content-Type de la requête — un attaquant peut les falsifier. Vérifiez le type MIME via les magic bytes (les premiers octets du fichier) : Apache Tika sur Java, libmagic sur C/C++, la commande file sur Linux, ou les outils intégrés du framework — Files.probeContentType() sur Java, mimetypes sur Python.

Résumé

  • Multipart Upload — un mécanisme pour transférer plusieurs parties hétérogènes dans une seule requête HTTP séparées par un boundary.
  • multipart/form-data — le type MIME standard pour télécharger des fichiers via des formulaires web et des applications mobiles, supporte le transfert binaire sans encodage.
  • Chaque partie de la requête contient ses propres en-têtes Content-Disposition et Content-Type, permettant d'envoyer des champs de différents types dans une seule requête.
  • Boundary — une chaîne délimitatrice unique, générée automatiquement par le client, qui ne doit pas apparaître dans les données transmises.
  • Avantages — une requête au lieu de plusieurs, transfert binaire sans encodage base64, support des fichiers de toute taille (avec une configuration serveur appropriée).
  • Limites — limites de taille sur le serveur, délais d'attente lors du téléchargement de fichiers volumineux, risque d'OutOfMemoryError sans traitement en streaming.
  • Sécurité — vérifiez le type MIME par le contenu du fichier, pas par l'extension ; stockez les fichiers en dehors du document-root et scannez-les à la recherche de virus.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi