Que signifie enctype= "multipart/form-data"?
que signifie enctype='multipart/form-data'
sous la forme HTML
et quand devrions-nous l'utiliser?
8 réponses
lorsque vous faites une requête POST, vous devez encoder les données qui forment le corps de la requête d'une manière ou d'une autre.
Les formulaires HTMLoffrent trois méthodes d'encodage.
-
application/x-www-form-urlencoded
(la valeur par défaut) -
multipart/form-data
-
text/plain
des travaux étaient en cours pour ajouter application/json
, mais cela a été abandonné.
les spécificités des formats n'ont pas d'importance pour la plupart des développeurs. Les points importants sont:
lorsque vous écrivez un code côté client, tout ce que vous devez savoir est utilisez multipart/form-data
lorsque votre formulaire comprend des <input type="file">
éléments .
lorsque vous écrivez du code côté serveur: utilisez une bibliothèque de gestion de formulaires pré-écrite (par exemple Perl CGI->param
ou celui exposé par PHP $_POST
superglobal) et il prendra soin des différences pour vous. Ne vous embêtez pas à essayer d'analyser les entrées brutes reçues par le serveur.
N'utilisez jamais text/plain
.
si vous écrivez (ou déboguez) une bibliothèque pour analyser ou générer les données brutes, alors vous devez commencer à vous soucier du format. Vous pourriez aussi vouloir le savoir pour intérêt.
application/x-www-form-urlencoded
est plus ou moins la même que la chaîne de requête à la fin de L'URL.
multipart/form-data
est beaucoup plus compliqué, mais il permet des fichiers entiers pour être inclus dans les données. Un exemple du résultat peut être trouvé dans la spécification HTML 4 .
text/plain
est introduit par HTML 5 et n'est utile que pour le débogage - de la spécification : ils ne sont pas interprétable de façon fiable par ordinateur - et je dirais que les autres combinés avec des outils (comme l'onglet Net dans les outils de développement de la plupart des navigateurs) sont mieux pour cela).
quand doit-on utiliser
la réponse de Quentin est juste: utilisez multipart/form-data
si le formulaire contient un téléchargement de fichier, et application/x-www-form-urlencoded
sinon, qui est la valeur par défaut si vous omettez enctype
.
je vais à:
- ajouter un peu plus de références HTML5
- expliquer pourquoi il a raison avec un formulaire soumettre l'exemple
HTML5 references
il y a trois possibilités pour enctype
:
-
x-www-urlencoded
-
multipart/form-data
(spec points à RFC7578 ) -
text-plain
. Ce n'est" pas interprétable de façon fiable par ordinateur", donc il devrait ne jamais être utilisé dans la production, et nous n'allons pas regarder plus loin.
comment générer les exemples
une fois que vous voyez un exemple de chaque méthode, il devient évident comment ils fonctionnent, et quand vous devriez utiliser chacun d'eux.
vous pouvez produire des exemples en utilisant:
-
nc -l
ou un serveur ECHO: serveur de test HTTP acceptant les requêtes GET / POST - un agent utilisateur comme un navigateur ou cURL
sauvegardez le formulaire dans un fichier .html
minimal:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>upload</title>
</head>
<body>
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
<p><input type="text" name="text1" value="text default">
<p><input type="text" name="text2" value="aωb">
<p><input type="file" name="file1">
<p><input type="file" name="file2">
<p><input type="file" name="file3">
<p><button type="submit">Submit</button>
</form>
</body>
</html>
nous avons défini la valeur par défaut du texte à aωb
, qui signifie aωb
parce que ω
est U+03C9
, qui sont les octets 61 CF 89 62
dans UTF-8.
créer des fichiers pour télécharger:
echo 'Content of a.txt.' > a.txt
echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html
# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary
exécuter notre petit serveur echo:
while true; do printf '' | nc -l 8000 localhost; done
ouvrez le HTML de votre navigateur, sélectionnez les fichiers et cliquez sur Soumettre et vérifiez le terminal.
nc
imprime la demande reçue.
testé sur Ubuntu 14.04.3, nc
BSD 1.105, Firefox 40.
multipart /form-data
Firefox envoyé:
POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"
text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"
aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain
Content of a.txt.
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html
<!DOCTYPE html><title>Content of a.html.</title>
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream
aωb
-----------------------------735323031399963166993862150--
Pour le fichier binaire et le champ de texte, les octets 61 CF 89 62
( aωb
in UTF-8) sont envoyés littéralement. Vous pouvez vérifier cela avec nc -l localhost 8000 | hd
, qui dit que les octets:
61 CF 89 62
ont été envoyés ( 61
= = " a " et 62
== 'b').
il est donc clair que:
-
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266
définit le type de contenu àmultipart/form-data
et indique que les champs sont séparés par la chaîne de caractèresboundary
. -
chaque champ reçoit des sous-en-têtes avant ses données:
Content-Disposition: form-data;
, le champname
, lefilename
, suivi des données.le serveur lit les données jusqu'à la chaîne de limite suivante. Le navigateur doit choisir une limite qui n'apparaissent pas dans les champs, c'est pourquoi la limite peut varier entre les demandes.
parce que nous avons la frontière unique, aucun encodage des données n'est nécessaire: données binaires est envoyé comme est.
TODO: Quelle est la taille optimale de la limite (
log(N)
je parie), et le nom / la durée d'exécution de l'algorithme qui le trouve? Demandé à: https://cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences -
Content-Type
est automatiquement déterminé par le navigateur.Comment il est déterminé exactement a demandé: Comment le type mime d'un fichier téléchargé déterminé par navigateur?
application / x-www-form-urlencoded
maintenant changer le enctype
en application/x-www-form-urlencoded
, recharger le navigateur, et soumettre à nouveau.
Firefox envoyé:
POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary
il est clair que les données du fichier n'ont pas été envoyées, seulement les noms de base. Donc cela ne peut pas être utilisé pour les fichiers.
quant au champ de texte, nous voyons que les caractères imprimables habituels comme a
et b
ont été envoyés en un octet, tandis que les caractères non imprimables comme 0xCF
et 0x89
ont pris 3 octets chacun: %CF%89
!
comparaison
Les téléchargements de fichierscontiennent souvent beaucoup de caractères non imprimables (par exemple des images), alors que les formes de texte ne le font presque jamais.
des exemples nous ont vu que:
-
multipart/form-data
: ajoute quelques bytes de limite supérieure au message, et doit passer un certain temps à le calculer, mais envoie chaque byte dans un byte. -
application/x-www-form-urlencoded
: a une limite de byte unique par champ (&
), mais ajoute un linéaire facteur de plafond de 3x pour chaque caractère non imprimable.
donc, même si nous pouvions envoyer des fichiers avec application/x-www-form-urlencoded
, nous ne le voudrions pas, parce que c'est tellement inefficace.
mais pour les caractères imprimables trouvés dans les champs de texte, il n'a pas d'importance et génère moins de frais généraux, donc nous l'utilisons.
enctype='multipart/form-data
est un type d'encodage qui permet d'envoyer des fichiers via un POST . Tout simplement, sans cet encodage, les fichiers ne peuvent pas être envoyés via POST .
Si vous voulez permettre à un utilisateur de télécharger un fichier via un formulaire, vous devez utiliser cette enctype .
lorsque vous soumettez un formulaire, vous essayez de dire à votre navigateur d'envoyer via le protocole HTTP un message sur le réseau correctement enveloppé dans une structure de message de protocole TCP/IP. Lors de l'envoi de données, vous pouvez utiliser POST
ou GET
méthodes pour envoyer des données en utilisant le protocole HTTP. POST
dit à votre navigateur de construire un message HTTP et de mettre tout le contenu dans le corps du message (Une façon très utile de faire les choses, plus sûr et aussi flexible). GET
a certaines contraintes concernant la représentation et la longueur des données.
en Indiquant ce que vous envoyer
lors de l'envoi d'un fichier, il est nécessaire de signaler au protocole HTTP que vous envoyez un fichier qui contient plusieurs caractéristiques et informations. De cette façon, il est possible d'envoyer régulièrement des données au destinataire et de le laisser ouvrir le fichier avec le format courant et ainsi de suite... C'est une exigence du protocole HTTP comme indiqué ici
vous ne pouvez pas envoyer de fichiers en utilisant les paramètres par défaut enctype
parce que votre récepteur pourrait rencontrer des problèmes de lecture (considérez qu'un fichier est un descripteur pour certaines données pour un système d'exploitation spécifique, si vous voyez les choses de cette façon, peut-être que vous comprendrez pourquoi il est si important de spécifier un enctype
différent pour les fichiers).
N'oubliez pas la sécurité
Cette façon de faire assure également que certains algorithmes de sécurité fonctionnent sur vos messages. Ces informations sont également utilisées par les routeurs au niveau de l'application afin d'agir comme de bons pare-feu pour les données externes.
Eh bien, comme vous pouvez le voir, ce n'est pas une chose stupide d'utiliser un enctype
spécifique pour les fichiers.
enctype='multipart/form-data'
signifie qu'aucun caractère ne sera encodé. c'est pourquoi ce type est utilisé pendant le téléchargement de fichiers vers le serveur.
Donc multipart/form-data
est utilisé lorsqu'un formulaire nécessite des données binaires, comme le contenu d'un fichier à charger
définit l'attribut method to POST car le contenu d'un fichier ne peut pas être placé à l'intérieur d'un paramètre URL à l'aide d'un formulaire.
définit la valeur d'enctype à multipart/form-data parce que les données seront divisées en plusieurs parties, une pour chaque fichier plus une pour le texte du corps de formulaire qui peut être envoyé avec eux.
- enctype ( ENC ode TYPE ) cet attribut spécifie comment les données-formulaires doivent être encodées lors de leur soumission au serveur.
- multipart/form-data est l'une des valeurs de l'attribut enctype, qui est utilisé dans l'élément de formulaire qui ont un téléchargement de fichier. multi-partie signifie le formulaire de données se divise en plusieurs parties et de l'envoyer au serveur.
- métaphore partie : un document HTML a deux parties : une tête et un corps.
habituellement, c'est quand vous avez un formulaire de poste qui doit prendre un téléchargement de fichier en tant que données... cela indiquera au serveur comment il va encoder les données transférées, dans ce cas, il ne sera pas encodé parce qu'il ne fera que Transférer et télécharger les fichiers vers le serveur, comme par exemple lors du téléchargement d'une image ou d'un pdf