Quelle est la limite des données en plusieurs parties / formulaires?

403

Je veux poser une question sur le multipart/form-data. Dans l'en-tête HTTP, je trouve que le Content-Type: multipart/form-data; boundary=???.

Le ???libre doit-il être défini par l'utilisateur? Ou est-il généré à partir du HTML? Est-il possible pour moi de définir le ??? = abcdefg?

Des questions
la source
2
J'ai trouvé que c'était la réponse. w3.org/TR/html401/interact/forms.html#h-17.13.4.2
Questions

Réponses:

424

Le ???libre doit-il être défini par l'utilisateur?

Oui.

ou est-il fourni par le HTML?

Non. HTML n'a rien à voir avec ça. Lire ci-dessous.

Est-il possible pour moi de définir le ???comme abcdefg?

Oui.

Si vous souhaitez envoyer les données suivantes au serveur Web:

name = John
age = 12

utiliser application/x-www-form-urlencodedserait comme ceci:

name=John&age=12

Comme vous pouvez le voir, le serveur sait que les paramètres sont séparés par une esperluette &. Si &une valeur de paramètre est requise, elle doit être codée.

Alors, comment le serveur sait-il où commence et se termine une valeur de paramètre lorsqu'il reçoit une demande HTTP en utilisant multipart/form-data?

Utilisation de la frontière , similaire à &.

Par exemple:

--XXX
Content-Disposition: form-data; name="name"

John
--XXX
Content-Disposition: form-data; name="age"

12
--XXX--

Dans ce cas, la valeur limite est XXX. Vous le spécifiez dans l'en- Content-Typetête afin que le serveur sache comment diviser les données qu'il reçoit.

Vous devez donc:

  • Utilisez une valeur qui n'apparaîtra pas dans les données HTTP envoyées au serveur.

  • Soyez cohérent et utilisez la même valeur partout dans le message de demande.

Oscar Mederos
la source
54
Vous devez ajouter un "-" supplémentaire à la fin de la limite.
Sebastian Piskorski
13
Vous pouvez le lire dans la documentation. Les limites doivent avoir deux hypens supplémentaires "-" Lien: w3.org/TR/html401/interact/forms.html#h-17.13.4.2
Sebastian Piskorski
6
Très bonne réponse. Une limite est juste la «clé» pour séparer les multiples «parties» d'une charge utile en plusieurs parties. Normalement, quelque chose comme «&» suffit pour séparer les variables, mais vous avez besoin de quelque chose de plus unique pour séparer les charges utiles au sein de la charge utile.
user2483724
1
@ K3rnel31 Bien sûr, à moins que la nouvelle chaîne limite ait la même longueur.
Oscar Mederos du
5
Je pense que la valeur limite telle que déclarée dans l'en-tête Content-Type sera en fait -XXX --- car un "-" supplémentaire devrait être écrit lors de la séparation des parties (d'où le --- XXX ---)
Theodore K .
96

La réponse exacte à la question est: oui, vous pouvez utiliser une valeur arbitraire pour le boundaryparamètre , étant donné qu'il ne dépasse pas 70 octets de longueur et se compose uniquement de caractères 7 bitsUS-ASCII (imprimables).

Si vous utilisez l' un des multipart/*types de contenu, vous êtes effectivement tenu de spécifier le boundaryparamètre dans l' en- Content-Typetête, sinon le serveur (dans le cas d'une requête HTTP) ne sera pas en mesure d'analyser la charge utile.

Vous souhaiterez probablement également définir le charsetparamètre UTF-8dans votre en- Content-Typetête, sauf si vous pouvez être absolument sûr que seul le US-ASCIIjeu de caractères sera utilisé dans les données de charge utile.

Quelques extraits pertinents de la RFC2046 :

  • 4.1.2. Paramètre de jeu de caractères:

    Contrairement à certaines autres valeurs de paramètre, les valeurs du paramètre charset ne sont PAS sensibles à la casse. Le jeu de caractères par défaut, qui doit être supposé en l'absence de paramètre charset, est US-ASCII.

  • 5.1. Type de support en plusieurs parties

    Comme indiqué dans la définition du champ Content-Transfer-Encoding [RFC 2045], aucun codage autre que "7bit", "8bit" ou "binary" n'est autorisé pour les entités de type "multipart". Les délimiteurs de limite "multipart" et les champs d'en-tête sont toujours représentés sous la forme US-ASCII 7 bits dans tous les cas (bien que les champs d'en-tête puissent coder le texte d'en-tête non-US-ASCII selon la RFC 2047) et les données dans les parties du corps peuvent être codées sur un partie par partie, avec des champs Content-Transfer-Encoding pour chaque partie de corps appropriée.

    Le champ Content-Type pour les entités à parties multiples nécessite un paramètre, "limite". La ligne de délimitation de limite est ensuite définie comme une ligne composée entièrement de deux caractères de trait d'union ("-", valeur décimale 45) suivi de la valeur du paramètre de limite du champ d'en-tête Content-Type, d'un espace linéaire facultatif et d'un CRLF de fin.

    Les délimiteurs de limite ne doivent pas apparaître dans le matériau encapsulé et ne doivent pas dépasser 70 caractères, sans compter les deux tirets de tête.

    La ligne de délimitation limite qui suit la dernière partie du corps est un délimiteur distinct qui indique qu'aucune autre partie du corps ne suivra. Une telle ligne de délimitation est identique aux lignes de délimitation précédentes, avec l'ajout de deux tirets supplémentaires après la valeur du paramètre de limite.

Voici un exemple utilisant une frontière arbitraire:

Content-Type: multipart/form-data; charset=utf-8; boundary="another cool boundary"

--another cool boundary
Content-Disposition: form-data; name="foo"

bar
--another cool boundary
Content-Disposition: form-data; name="baz"

quux
--another cool boundary--
antichris
la source
2
J'aime cette réponse parce qu'elle cite de RFC sur la façon dont les tirets sont spécifiés.
Rick
@Rick Il y a une raison valable pour que l'IETF fasse cela - bien qu'ils se ressemblent tous à peu près, un seul des quatre suivants est le caractère de trait d'union correct: ˗ - - -
antichris
ha, quand j'ai dit hypens, je veux dire votre réponse m'a dit quels hypens sont définis dans la norme. Je ne savais pas trop quels hypens étaient "définis par le client" et lesquels étaient "définis par les spécifications"
Rick
31

multipart / form-data contient une limite pour séparer les paires nom / valeur. La limite agit comme un marqueur de chaque bloc de paires nom / valeur transmis lorsqu'un formulaire est soumis. La limite est automatiquement ajoutée à un type de contenu d'un en-tête de demande.

Le formulaire avec l' attribut enctype = "multipart / form-data" aura un en-tête de demande Content-Type: multipart / form-data; limite --- WebKit193844043-h ( valeur générée par le navigateur ).

La charge utile passée ressemble à ceci:

Content-Type: multipart/form-data; boundary=---WebKitFormBoundary7MA4YWxkTrZu0gW

    -----WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name=”file”; filename=”captcha
    Content-Type:

    -----WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name=”action

    submit
    -----WebKitFormBoundary7MA4YWxkTrZu0gW--

Côté service Web, il est consommé sous forme @Consumes ("multipart / form-data").

Attention, lorsque vous testez votre service Web à l'aide de Chrome Postman, vous devez cocher l'option de données de formulaire (bouton radio) et le menu Fichier dans la liste déroulante pour envoyer la pièce jointe. La fourniture explicite de type de contenu en tant que données de partie / formulaire génère une erreur. Parce que la frontière est manquante car elle remplace la demande de curl de post man au serveur avec le type de contenu en ajoutant la frontière qui fonctionne bien.

Voir RFC1341 sec7.2 Le type de contenu en plusieurs parties

Yergalem
la source