Content-Type dans le développement web : définition, types MIME et fonctionnement

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

Content-Type est un en-tête HTTP qui spécifie le format des données transmises entre un client et un serveur. Sans le type MIME correct, le navigateur ne peut pas traiter correctement la réponse : un fichier texte s'affiche comme du code brut et une image ne s'ouvre pas. Selon MDN Web Docs, 2025, Content-Type est obligatoire pour la transmission correcte de données de tout type dans le protocole HTTP et détermine comment le destinataire interprète le corps du message.

Points clés

  • Content-Type est un en-tête HTTP qui définit le type MIME des données transmises dans le corps d'une requête ou d'une réponse.
  • Le type MIME se compose d'une catégorie principale et d'un sous-type séparés par une barre oblique — par exemple, text/html ou application/json.
  • Le paramètre charset spécifie l'encodage pour les types MIME texte ; UTF-8 est la norme pour le web.
  • Sans Content-Type, le navigateur active le MIME sniffing, ce qui entraîne des erreurs d'affichage et des vulnérabilités de sécurité.
  • L'en-tête X-Content-Type-Options: nosniff désactive la devinette de type et renforce la sécurité des applications web.

Qu'est-ce que Content-Type ?

Content-Type est un en-tête HTTP du groupe des en-têtes de représentation qui informe le destinataire du format des données dans le corps du message. Il est obligatoire pour les requêtes et réponses HTTP qui contiennent un corps, et sans lui le client ne peut pas interpréter correctement les octets reçus. En fonction de Content-Type, le navigateur ou l'application mobile sélectionne un analyseur : pour text/html il lance le moteur HTML, pour image/png — le décodeur PNG, pour application/json — l'analyseur JSON.

La valeur de Content-Type est un type MIME — un identifiant standardisé pour les formats de données. L'acronyme MIME signifie Multipurpose Internet Mail Extensions, car cette norme a été créée à l'origine pour les pièces jointes des e-mails. Cependant, elle est devenue la base de HTTP et est aujourd'hui utilisée partout — de la transmission de pages web à l'échange de données dans les API REST. Chaque type MIME se compose de deux parties : une catégorie principale et un sous-type qualificatif, séparés par une barre oblique.

Le paramètre charset complète Content-Type pour les formats texte. Par exemple, Content-Type: text/html; charset=utf-8 indique qu'un document HTML est transmis en encodage UTF-8. Selon l'IETF RFC 7231, section 3.1.1.5, l'en-tête Content-Type est obligatoire pour les messages HTTP contenant un corps, et son absence est traitée comme application/octet-stream ou conduit à du MIME sniffing.

Histoire des types MIME dans HTTP

Le protocole HTTP/0.9, publié en 1991, ne transmettait que des pages HTML, donc le type de données était implicite par défaut. Avec l'introduction de HTTP/1.0 dans la RFC 1945, les développeurs ont réalisé la nécessité de transmettre des images, des feuilles de style et des scripts. Ils ont adapté la norme MIME du protocole de messagerie, et Content-Type est devenu une partie intégrante de HTTP. Depuis lors, le registre IANA s'est étendu à des centaines de valeurs — du familier text/html aux modernes image/avif et application/manifest+json.

Le rôle de Content-Type dans la sécurité

Content-Type joue un rôle critique dans la protection contre les attaques. Si un serveur envoie un fichier HTML avec le type MIME text/plain, le navigateur n'exécutera pas JavaScript ni ne construira le DOM — cela prévient les attaques XSS. L'en-tête X-Content-Type-Options: nosniff, recommandé par OWASP, interdit complètement au navigateur de deviner le type MIME en fonction du contenu. Selon PortSwigger Research, les attaques de MIME sniffing étaient particulièrement répandues dans Internet Explorer 6-9, où le navigateur ignorait Content-Type et déterminait le type à partir des premiers octets du fichier.

Structure du type MIME

Un type MIME est spécifié au format type/subtype, où type est la catégorie générale des données et subtype est le format spécifique à l'intérieur de celle-ci. Par exemple, dans image/png, la catégorie image indique une image et le sous-type png spécifie le format Portable Network Graphics. Il n'existe que quelques catégories : text, image, audio, video, application, multipart et message. Le reste de la diversité provient des sous-types, dont il existe des centaines.

Les paramètres supplémentaires sont transmis par un point-virgule après le sous-type. Le paramètre le plus courant est charset pour spécifier l'encodage. Content-Type: application/json; charset=utf-8 indique qu'un document JSON est transmis en encodage UTF-8. Formellement, charset pour application/json est redondant car JSON est toujours en UTF-8 selon la RFC 8259, mais la spécification explicite améliore la compatibilité avec les anciens clients HTTP.

CatégorieExemples de sous-typesDescription
texthtml, plain, css, javascript, csvFormats texte lisibles par l'homme
imagejpeg, png, gif, webp, svg+xml, avifImages raster et vectorielles
audiompeg, ogg, wav, mp4, webmFormats audio pour la lecture en streaming
videomp4, webm, ogg, x-msvideo, 3gppFormats vidéo et conteneurs multimédia
applicationjson, xml, pdf, zip, octet-stream, protobufDonnées binaires et structurées
multipartform-data, mixed, alternative, byterangesDocuments composites à plusieurs parties

Types MIME standard et non standard

Les types MIME standard sont enregistrés dans le registre IANA et ont un préfixe de catégorie principale. Les types non standard (spécifiques au fournisseur) utilisent le préfixe x- ou le format vnd.company.type — par exemple, application/vnd.google-earth.kml+xml pour le format KML de Google. Les navigateurs peuvent ne pas reconnaître les types non standard, donc pour les pièces jointes inconnues, on utilise application/octet-stream — un flux binaire universel que le navigateur n'essaie pas d'afficher mais propose de télécharger comme fichier.

Le paramètre charset en pratique

Le paramètre charset est essentiel pour l'affichage correct du texte. Sans lui, le navigateur peut mal interpréter les caractères, conduisant à du mojibake. La norme pour le web est UTF-8, mais on trouve également ISO-8859-1 (Latin-1) pour les langues d'Europe occidentale et windows-1251 pour le cyrillique sur les anciens sites. La recommandation du W3C est de toujours spécifier charset=utf-8 pour text/html et text/plain, tandis que charset n'est pas nécessaire pour application/json.

Types courants de Content-Type

En pratique, les développeurs web et mobiles travaillent avec un ensemble limité de types MIME. La connaissance de ces types est essentielle pour configurer correctement les serveurs, écrire des clients HTTP et gérer les fichiers statiques. text/html est le type principal pour les pages web, retourné par les serveurs Apache et Nginx par défaut pour les fichiers HTML. application/xhtml+xml est moins utilisé et uniquement pour les documents XHTML.

application/json est devenu la norme pour les API REST. Les serveurs retournent des données JSON avec ce type MIME, et les clients l'envoient dans les requêtes POST et PUT. text/javascript (obsolète) et application/javascript sont utilisés pour les fichiers JavaScript. Selon l'enquête W3Techs, 2025, JSON est le format de données qui connaît la croissance la plus rapide sur le web, dépassant XML en 2018. Pour les services SOAP, text/xml ou application/soap+xml sont encore utilisés.

Pour les images, le type MIME est déterminé par le format du fichier : image/jpeg pour JPEG, image/png pour PNG, image/gif pour GIF, image/webp pour le format moderne WebP. image/svg+xml est utilisé pour les graphiques vectoriels et prend en charge les styles et scripts intégrés. video/mp4, audio/mpeg et application/pdf sont d'autres types fréquemment rencontrés. Pour les polices web, on utilise font/woff2, font/woff et font/ttf.

Content-Type dans le téléchargement de fichiers

Lors du téléchargement de fichiers via un formulaire HTML, on utilise multipart/form-data — un type MIME composite qui divise la requête en plusieurs parties. Chaque partie a son propre en-tête Content-Type et Content-Disposition spécifiant le nom du champ et le nom original du fichier. Le serveur reçoit le fichier avec son type MIME réel déterminé par le navigateur et peut le vérifier côté backend. application/octet-stream est utilisé pour les fichiers de type inconnu — le navigateur n'essaie pas d'afficher le contenu mais propose de le sauvegarder sur le disque.

Impact de Content-Type sur la mise en cache

Le type MIME affecte la politique de mise en cache des CDN et des navigateurs. Les images avec des URL stables sont généralement mises en cache pour une longue durée (un an ou plus), tandis que les pages HTML sont mises en cache pour des minutes ou des secondes. Les serveurs CDN comme Cloudflare et Akamai utilisent Content-Type pour sélectionner l'algorithme de compression : text/* est compressé avec gzip ou brotli, image/* ne l'est pas, car les images sont déjà compressées. La configuration correcte de Content-Type sur le serveur impacte directement les performances de chargement des pages web et des applications mobiles.

Comment le serveur et le client utilisent Content-Type

Le serveur définit l'en-tête Content-Type dans la réponse HTTP en fonction du type du fichier demandé ou du contenu généré dynamiquement. Les serveurs web populaires comme Nginx et Apache ont des tables de types MIME intégrées qui associent les extensions de fichier au Content-Type correspondant. Par exemple, index.html reçoit text/html et style.css reçoit text/css. Pour les réponses dynamiques, le développeur définit Content-Type dans le code de l'application en PHP, Python, Java ou Kotlin.

Le client utilise Content-Type pour sélectionner un gestionnaire. Si le serveur retourne text/html, le navigateur lance l'analyseur HTML et construit l'arbre DOM. Si image/png — il lance le décodeur PNG. Si Content-Type est absent ou incorrect, le client applique le MIME sniffing — il essaie de deviner le type par la signature (octets magiques) au début du fichier. JPEG commence par les octets FF D8 FF, PNG commence par 89 50 4E 47, et PDF commence par 25 50 44 46. Ce processus est potentiellement dangereux et est désactivé par l'en-tête X-Content-Type-Options: nosniff.

Dans les applications mobiles, Content-Type est géré par les clients HTTP. OkHttp sur Android analyse automatiquement l'en-tête Content-Type de la réponse et le fournit via la méthode Response.header("Content-Type"). Le client URLSession d'iOS fait de même via la propriété URLResponse.mimeType. Sur les deux plateformes, Content-Type est utilisé pour sélectionner un analyseur : JSON — via Moshi ou Gson sur Android, via Codable sur iOS ; images — via Glide, Coil ou SDWebImage.

Négociation de contenu via Accept et Content-Type

La négociation de contenu est un mécanisme HTTP où le client spécifie le format de réponse souhaité via l'en-tête Accept, et le serveur sélectionne le format approprié et le retourne avec le Content-Type correspondant. Par exemple, le client envoie Accept: application/json, le serveur répond avec Content-Type: application/json. Si le serveur ne peut pas fournir le format demandé, il retourne 406 Not Acceptable. Dans les API REST, ce mécanisme permet à un seul point de terminaison de retourner des données en JSON, XML ou HTML.

Content-Type dans les requêtes et réponses

L'en-tête Content-Type est utilisé à la fois dans les requêtes HTTP et les réponses HTTP. Dans les requêtes, il spécifie le format du corps de la requête, par exemple lors de l'envoi de JSON via POST. Dans les réponses, il spécifie le format des données retournées. La différence clé est que le Content-Type de la requête est défini par le client, tandis que le Content-Type de la réponse est défini par le serveur. Définir incorrectement Content-Type dans une requête empêche le serveur d'analyser le corps, retournant une erreur 400 Bad Request ou 415 Unsupported Media Type.

Dans les requêtes HTTP, Content-Type est obligatoire pour les méthodes POST, PUT et PATCH si la requête contient un corps. GET, HEAD et DELETE n'utilisent généralement pas de corps, donc Content-Type n'est pas spécifié ou est ignoré pour eux. Lors de la soumission d'un formulaire HTML avec l'attribut enctype="multipart/form-data", le navigateur définit automatiquement Content-Type: multipart/form-data avec une chaîne de limite unique qui sépare les parties de la requête composite. Chaque partie est séparée par --boundary, et la fin de la requête est marquée par --boundary--.

Dans les réponses HTTP, Content-Type est défini par le serveur. Si le serveur ne spécifie pas Content-Type, le client active le MIME sniffing ou traite la réponse comme application/octet-stream. La méthode HTTP HEAD permet d'obtenir les en-têtes de réponse, y compris Content-Type, sans transmettre le corps. Ceci est utile pour vérifier le type de ressource avant de la charger complètement. Les serveurs CDN peuvent remplacer Content-Type lors de la transformation du contenu — par exemple, lors de la conversion d'images en WebP.

kotlin
import okhttp3.*

fun checkContentType() {
    val client = OkHttpClient()
    val request = Request.Builder()
        .url("https://api.example.com/resource")
        .head()
        .build()

    client.newCall(request).execute().use { response ->
        val contentType = response.header("Content-Type")
        val mediaType = MediaType.parse(contentType)
        println("Type : ${mediaType?.type}, Sous-type : ${mediaType?.subtype}")
    }
}

Content-Type dans les clients HTTP mobiles

Dans le développement mobile, l'en-tête Content-Type est géré automatiquement par les clients HTTP. Dans OkHttp sur Android, Content-Type est défini via RequestBody : val body = "{}".toRequestBody("application/json".toMediaType()). Retrofit gère Content-Type via des annotations : @Body pour JSON, @Part pour multipart. Sur iOS, URLSession définit Content-Type pour HTTPBody, et Alamofire le fait via le paramètre encoding : JSONEncoding.default ou URLEncoding.default. La définition manuelle de Content-Type est nécessaire lors du travail avec des sockets bruts ou des protocoles personnalisés.

Erreurs de Content-Type

Un Content-Type incorrect est l'un des problèmes les plus courants dans le développement et l'intégration de services web. L'erreur la plus fréquente est lorsque le serveur retourne text/html au lieu de application/json. Le client reçoit JSON comme une chaîne HTML, ne peut pas l'analyser et lève une exception. Cela se produit lorsque le framework web est configuré pour HTML par défaut et que le développeur oublie de remplacer Content-Type pour les points de terminaison d'API. En PHP, cela se manifeste par l'absence de header('Content-Type: application/json'), dans Spring Boot — par l'absence de l'annotation produces.

La deuxième erreur la plus courante est un charset incorrect ou manquant. Si le serveur envoie text/html; charset=iso-8859-1 et que le navigateur attend UTF-8, les caractères cyrilliques s'affichent comme du mojibake. Ce problème est typique des anciens sites qui n'ont pas migré vers UTF-8. Pour JSON, cette erreur est moins courante car la RFC 8259 prescrit UTF-8 sans négociation supplémentaire. La solution est de toujours spécifier explicitement charset=utf-8 pour les types MIME texte dans la configuration du serveur.

Le troisième problème est la non-concordance entre Content-Type et le contenu réel. Si le serveur envoie Content-Type: image/png mais que le corps de la réponse contient une image WebP, le navigateur peut ne pas la décoder. Les serveurs CDN compriment parfois les images en changeant le format mais sans mettre à jour l'en-tête Content-Type. Vérifier la correspondance de Content-Type avec le contenu réel est une étape obligatoire dans les tests d'API et les tests d'intégration des applications mobiles.

Diagnostic et correction des erreurs de Content-Type

Pour le débogage, utilisez les outils de développement du navigateur (onglet Network), curl avec le drapeau -I pour vérifier les en-têtes de réponse, ou des analyseurs de trafic comme Charles Proxy et Wireshark. Nginx est configuré via la directive include mime.types, Apache — via AddType et AddDefaultCharset. Pour les fichiers statiques, vérifiez toujours que l'extension du fichier correspond à son type MIME. Pour les réponses dynamiques dans tous les langages de programmation, définissez explicitement Content-Type avant de générer les données — cela prévient la grande majorité des problèmes.

Questions fréquentes

Que se passe-t-il si Content-Type n'est pas spécifié dans une réponse HTTP ?

Sans Content-Type, le navigateur active le MIME sniffing — analyse des premiers octets de la réponse pour déterminer automatiquement le type de données. Cela peut entraîner un traitement incorrect du contenu et des vulnérabilités de sécurité. Les navigateurs modernes avec l'en-tête X-Content-Type-Options: nosniff bloquent complètement la devinette.

Quelle est la différence entre Content-Type et Accept en HTTP ?

Content-Type spécifie le format des données transmises dans le message actuel (corps de la requête ou de la réponse). Accept est un en-tête de requête qui indique au serveur quel format de réponse le client préfère. Content-Type est défini par l'expéditeur des données, tandis qu'Accept est défini par le destinataire, et ils participent tous deux au mécanisme de négociation de contenu.

Quel est le Content-Type correct pour JSON ?

Le type MIME officiel pour JSON est application/json selon la RFC 8259. Auparavant, text/x-json était utilisé, mais ce type est obsolète. Le paramètre charset pour application/json n'est pas nécessaire car JSON est toujours transmis en encodage UTF-8, UTF-16 ou UTF-32 avec détection automatique de l'ordre des octets (BOM) selon la spécification.

Pourquoi le serveur retourne-t-il text/html au lieu de application/json ?

Cela se produit lorsque le framework web ne remplace pas le Content-Type par défaut pour les points de terminaison d'API. En PHP, cela se corrige en appelant header('Content-Type: application/json'), dans Spring Boot — avec l'annotation @GetMapping(produces = "application/json"), dans Express.js — avec la méthode res.set('Content-Type', 'application/json').

Que signifie Content-Type: application/octet-stream ?

application/octet-stream est un type MIME universel pour les données binaires dont le format est inconnu. Le navigateur n'essaie pas d'afficher un tel fichier dans la fenêtre mais propose de le sauvegarder sur le disque. Il est utilisé pour les téléchargements de fichiers, les pièces jointes d'e-mails et les données en streaming lorsque le serveur ne peut pas déterminer le type exact du contenu transmis.

Résumé

  • Content-Type est un en-tête HTTP qui définit le type MIME des données transmises, obligatoire pour les messages avec corps.
  • Le type MIME se compose d'une catégorie (text, image, application) et d'un sous-type (html, json, png), séparés par une barre oblique — par exemple, text/html ou application/json.
  • Le paramètre charset spécifie l'encodage pour les types texte ; la norme web est UTF-8, et la spécification explicite évite les problèmes d'affichage des caractères.
  • Content-Type est utilisé à la fois dans les requêtes (POST, PUT) et les réponses, affectant la sélection de l'analyseur et le traitement des données par le client.
  • Les erreurs de Content-Type entraînent un affichage incorrect, des problèmes d'analyse, des erreurs 400/415 et des vulnérabilités de MIME sniffing.
  • L'en-tête X-Content-Type-Options: nosniff désactive la devinette du type MIME par le navigateur et est recommandé par OWASP pour toutes les applications web.
  • La vérification de Content-Type dans les tests d'API est obligatoire — chaque point de terminaison doit retourner le type MIME attendu correspondant au contenu réel de la réponse.

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