Que signifie enctype= "multipart/form-data"?

que signifie enctype='multipart/form-data' sous la forme HTML et quand devrions-nous l'utiliser?

1058
demandé sur Daryl Bennett 2010-12-24 15:19:27

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 HTML

offrent 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).

1190
répondu Quentin 2015-10-15 08:35:51

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 :

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:

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&#x03C9;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&#x03C9;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ères boundary .

  • chaque champ reçoit des sous-en-têtes avant ses données: Content-Disposition: form-data; , le champ name , le filename , 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 fichiers

contiennent 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.

310

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 .

73
répondu Matt Asbury 2012-12-12 11:30:07

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.

68
répondu Andry 2017-08-02 06:42:41

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

29
répondu GP Singh 2014-10-13 21:09:54

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.

9
répondu sandy 2013-09-25 11:53:43
  • 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.
1
répondu Premraj 2017-11-08 00:12:22

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

0
répondu Eric 2016-03-10 09:29:45