web-dev-qa-db-fra.com

Pourquoi le formulaire enctype = multipart / form-data est-il requis lors du téléchargement d'un fichier?

Pourquoi est-ce <form enctype=multipart/form-data> requis lors du téléchargement d'un fichier sur un serveur Web?

44
Devi

Cela a à voir avec la façon dont le navigateur conditionne les données binaires et de formulaire pour la transmission via HTTP. Par défaut, seules les données du formulaire sont envoyées, mais si le formulaire doit prendre en charge le téléchargement d'un fichier, les données binaires doivent également être ajoutées et séparées des données du formulaire.

Scott Hanselman en donne une bonne explication ici :

HTTP et fonctionnement du téléchargement de fichiers via HTTP

Il est toujours préférable, pour moi, de comprendre POURQUOI et COMMENT quelque chose se passe. Si vous dites "simplement parce que" ou "peu importe, vous ajoutez simplement cela, et cela fonctionne", alors je pense que c'est triste. Pour une raison quelconque, alors que de nombreuses personnes comprennent les FORM POST et généralement comment les données du formulaire sont transmises au serveur, lorsqu'un fichier est transféré, beaucoup concluent que c'est magique. Pourquoi devons-nous ajouter enctype = "multipart/form = data" sur nos formulaires qui incluent les téléchargements de fichiers? Parce que le formulaire sera désormais POSTé en plusieurs parties.

Si vous avez un formulaire comme celui-ci:

<form action="/home/uploadfiles" method="post" enctype="multipart/form-data">
    <label for="file">Filename:</label>
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" value="Submit" />
</form>

Le formulaire résultant POST ressemblera à ceci (légèrement simplifié):

POST /home/uploadfiles HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------7d81b516112482 
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 324

-----------------------------7d81b516112482 
Content-Disposition: form-data; name="file"; filename="\\SERVER\Users\Scott\test.txt"
Content-Type: text/plain

foo
-----------------------------7d81b516112482
Content-Disposition: form-data; name="submit"

Submit
-----------------------------7d81b516112482--

Remarquez quelques choses à propos de ce POST. Tout d'abord, notez le type de contenu et la limite = "" et comment la limite est utilisée plus tard, comme exactement cela, une frontière entre les multiples parties. Voyez comment la première partie montre que j'ai téléchargé un seul fichier, de type text/plain. Vous pouvez interpoler à partir de cela la façon dont vous vous attendriez à ce que plusieurs fichiers s'affichent s'ils étaient tous POST en même temps.

Et bien sûr, regardez à quel point cela serait différent s'il ne s'agissait que d'un formulaire de base POST sans enctype = "multipart/form = data" inclus:

POST /home/uploadfiles HTTP/1.1 
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 13

submit=Submit

Voyez comment le type de contenu est différent? Il s'agit d'un POST sous forme régulière et typique. Peut-être atypique en ce qu'il ne comprend qu'un bouton Soumettre! ....

Soit dit en passant, si vous regardiez un de vos e-mails avec plusieurs fichiers joints, il ressemblerait TRÈS au corps du premier message HTTP, car l'encodage MIME en plusieurs parties se trouve partout, comme cela est courant avec la plupart des bonnes idées.

74
Nathan Taylor

Cela fait partie de la spécification pour le téléchargement de fichiers HTML comme décrit dans RFC-1867 , qui était la proposition d'autoriser les téléchargements de fichiers dans des formulaires HTML (vers 1995).

De la section 2:

Cette proposition apporte deux modifications au HTML:

1) Ajoutez une option FILE pour l'attribut TYPE de INPUT.
2) Autoriser un attribut ACCEPT pour la balise INPUT, qui est une liste de types de médias ou de modèles de type autorisés pour l'entrée.

De plus, il définit un nouveau type de média MIME, multipart/form-data , et spécifie le comportement des agents utilisateurs HTML lors de l'interprétation d'un
formulaire avec ENCTYPE="multipart/form-data" et/ou <INPUT type="file">
Mots clés.

Lorsque vous définissez enctype sur multipart/form-data, le navigateur sépare chaque fichier ou pièce jointe dans le téléchargement par une "limite en plusieurs parties", qui est un identifiant unique qui définit le début et la fin de chaque "partie".

Cela permet au navigateur d'envoyer plusieurs parties (d'où le nom) en une seule demande, et d'identifier chacune avec ses propres métadonnées comme le type MIME, le nom de fichier, etc.

2
isapir