Niveau Niveau débutant

Qu'est-ce qu'un type MIME ?

Articleformats

Publié par le (6673 lectures)

MIME type

Un type MIME est un mécanisme utilisé pour indiquer le type de contenu d'un fichier transmis sur Internet (et ce de multiples façons), à l'aide d'un format très simple : type/sous-type.

Un type qui mime.

Historiquement, MIME signifie Multipurpose Internet Mail Extensions, et provient donc du monde de l'e-mail. Mais on le retrouve partout sur le web, et en particulier avec le protocole HTTP qui fait fonctionner la navigation de tous les jours.

Parmi les exemples les plus célèbres :

Type MIME Format de fichier
text/plain Texte simple
text/html Document HTML
image/gif Image GIF
image/png Image PNG
image/jpeg Image JPEG
image/svg+xml Image SVG
audio/mp3 Son MP3
video/mp4 Vidéo MP4
application/javascript Code JavaScript
application/json JSON
application/pdf Document PDF
font/woff Police WOFF
font/woff2 Police WOFF v2
application/vnd.ms-excel Microsoft Excel
application/x-7z-compressed Compression au format 7zip

Et ainsi de suite : vous saisissez le concept. Une liste assez impressionnante de types reconnus est tenue à jour par l'IANA Internet Assigned Numbers Authority.

Les formats propriétaires peuvent être préfixés par .vnd comme vendor, d'autres par x- ce qui permet une certaine liberté d'invention. Flash s'en souvient avec application/x-shockwave-flash.

On peut aussi ajouter une précision supplémentaire sur l'encodage text/html; charset=UTF-8 pour un document HTML en UTF-8, ou video/ogg; codecs="theora, vorbis" pour de la vidéo dont le conteneur est Ogg et dont les codecs internes sont Theora pour la vidéo combiné à Vorbis pour l'audio. Cela engendre une grande possibilité de tests et de combinaisons : https://cconcolato.github.io/media-mime-support/. En JavaScript, la méthode canPlayType() qui équipe les éléments média (audio, video) indique si le navigateur pourrait décoder le format qui lui est proposé.

Lorsqu'un type est inconnu on utilise application/octet-stream, ce qui d'un point de vue navigateur web va simplement déclencher un téléchargement brut.

Pourquoi ?

Annoncer un type de contenu est important pour permettre au programme devant le recevoir (ex: le navigateur) de bien savoir s'il est en mesure d'en faire quelque chose d'utile : l'afficher de manière brute, ou le passer au module adéquat, par exemple une bibliothèque de décodage d'image PNG pour une image PNG, la bibliothèque ffmpeg pour les vidéos, etc. On ne se fie donc pas à l'extension du fichier, comme c'est le cas par défaut sur la plupart des systèmes d'exploitation.

Côté navigateur

Les requêtes HTTP contiennent à la fois, à l'envoi et à la réception, des instructions exploitant les types MIME. Vous pouvez les visualiser facilement dans les outils de développement (devtools, F12, etc), onglet Réseau ou Network.

Envoi

À l'envoi le navigateur annonce au serveur ce qu'il peut reconnaître, parmi autres informations, via l'en-tête Accept.

GET / HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7

On remarquera aussi dans ce dernier exemple qu'il sait reconnaître des algorithmes de compression (gzip, deflate, brotli), et qu'il indique le code langue préféré.

Réception

À la réception, le navigateur reçoit du serveur le type MIME du fichier livré, que ce soit pour la page HTML, ses images, ses médias, ses ressources CSS, JavaScript, la totale. Si un type ne correspond pas au contenu réel, cela peut engendrer un refus d'interprétation, notamment par mesure de sécurité.

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 11 Oct 2023 20:07:36 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip

Sécurité : le MIME éthique

Ainsi, on ne se base pas sur l'extension des fichiers qui peut facilement être modifiée. Cela fait partie également des directives de sécurité que l'on peut véhiculer via HTTP : voir Tour d’horizon sur HTTPS et les en-têtes de sécurité avec l'en-tête X-Content-Type-Options "nosniff" indiquant au navigateur qu'il ne doit pas essayer de "deviner" un type non indiqué.

Le sniffing et la rétro-compatibilité ne se font pas au hasard, il existe une spécifiaction précise et à jour pour mener à bien cette opération délicate : MIME Sniffing.

Ainsi, on pourra y découvrir que pour des raisons historique, JavaScript peut être reconnu par tous les types MIME suivants :

application/ecmascript
application/javascript
application/x-ecmascript
application/x-javascript
text/ecmascript
text/javascript
text/javascript1.0
text/javascript1.1
text/javascript1.2
text/javascript1.3
text/javascript1.4
text/javascript1.5
text/jscript
text/livescript
text/x-ecmascript
text/x-javascript

Ouf.

Back-end

L'envoi des en-têtes se fait souvent de manière transparente, même lorsqu'on développe, par le serveur web car celui-ci est déjà bien configuré par défaut. Sinon, on peut les ajouter ou les modifier grâce à la plupart des langages back-end, tels que PHP et sa fonction header :

<?php
header('Content-Type: text/html');
// ...

Dans les e-mails

Puisque c'est du protocole d'échange d'e-mails qu'est issue cette technique, mentionnons que les codes sources des e-mails (que vous pouvez très simplement consulter dans votre client de messagerie favori, Ctrl+U dans Mozilla Thunderbird) exposent assez clairement les types MIME par des instructions Content-Type. Tout comme HTTP.

Vous retrouverez ainsi dans les en-têtes de début du mail une déclaration telle que :

MIME-Version: 1.0

Puis à quelques encablures, annonçant la partie en texte brut :

Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Puis, encore plus loin, l'équivalent pour la version mise en forme avec HTML :

Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Et enfin, en préambule de chacune des pièces jointes :

Content-Type: application/pdf; name="document.pdf"
Content-Disposition: attachment; filename="document.pdf"
Content-Transfer-Encoding: base64

Suivi de tout le contenu du fichier encodé en base64. Basique mais efficace.

Type composé multipart

Le type multipart/form-data est pensé pour gérer des formulaires web transmettant plusieurs formats de données simultanément, et notamment lorsqu'il y a un fichier joint présent par un champ <input type="file">. Ainsi il faudra déclarer le formulaire avec un attribut enctype :

<form method="post" enctype="multipart/form-data">
  <input type="text" name="unchamptexte">
  <input type="file" name="unfichier">
  <input type="submit" value="Envoyer">
</form>

(Cet exemple n'est pas exhaustif, volontairement simplifié pour l'explication, pensez à le rendre propre et accessible avec des balises <label>).

Vous pourrez ensuite analyser l'envoi, toujours dans l'onglet Réseau de vos outils de développement, en examinant la requête HTTP. Celle-ci comprendra bien une déclaration Content-Type: multipart/form-data suivi d'un paramètre boundary indiquant quelle chaîne de caractère va séparer les différentes entités empaquetées dans la requête.

Content-Type: multipart/form-data; boundary=---------------------------xxx
Content-Length: 436

-----------------------------xxx
Content-Disposition: form-data; name="unchamptexte"

Besser e stick Brot im Sack, as e Fedder am Huet.
-----------------------------xxx
Content-Disposition: form-data; name="unfichier"; filename="hopla.txt"
Content-Type: text/plain

Lorem Elsass ipsum dui kuglopf geht's Pellentesque dolor mollis schneck semper so knepfle Pfourtz !

Le Secret du MIME n'en est plus un désormais !

Commenter

Vous devez être inscrit et identifié pour utiliser cette fonction.

Connectez-vous (déjà inscrit)

Oubli de mot de passe ? Pas de panique, on va le retrouver

Pas encore inscrit ? C'est très simple et gratuit.