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 ???
est-il libre d'être défini par l'utilisateur? Ou est-ce généré à partir du HTML? Est-il possible pour moi de définir le ??? = abcdefg
?
Le
???
est-il libre d'être défini par l'utilisateur?
Oui.
ou est-ce fourni par le HTML?
Non. HTML a rien à faire avec cela. Lire ci-dessous.
Est-il possible pour moi de définir le
???
commeabcdefg
?
Oui.
Si vous souhaitez envoyer les données suivantes au serveur Web:
name = John
age = 12
en utilisant application/x-www-form-urlencoded
serait comme ceci:
name=John&age=12
Comme vous pouvez le constater, le serveur sait que les paramètres sont séparés par une esperluette &
. Si &
est requis pour une valeur de paramètre, celle-ci doit alors être codée.
Alors, comment le serveur sait-il où une valeur de paramètre commence et se termine lorsqu'il reçoit une demande HTTP à l'aide de multipart/form-data
?
Utilisation de la limite , 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-tête Content-Type
pour que le serveur sache comment fractionner le les données qu'il reçoit.
Donc vous devez:
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 requête.
La réponse exacte à la question est: oui, vous pouvez utiliser une valeur arbitraire pour le paramètre boundary
, dans la mesure où il ne dépasse pas 70 octets. de longueur et se compose uniquement de 7-bit US-ASCII
(imprimable) caractères.
Si vous utilisez l'un des types de contenu multipart/*
, vous êtes en fait requis pour spécifier le paramètre boundary
dans l'en-tête Content-Type
, sinon le serveur (dans le cas d'une requête HTTP) ne sera pas capable d'analyser la charge utile.
Vous voudrez probablement également définir le paramètre charset
sur UTF-8
dans votre en-tête Content-Type
, à moins que vous ne soyez absolument sûr que seul le jeu de caractères US-ASCII
sera utilisé dans les données utiles.
Quelques extraits pertinents de la RFC2046 :
4.1.2. Paramètre de jeu de caractères:
Contrairement à d'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 d'un 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 "7 bits", "8 bits" ou "binaire" n'est autorisé pour les entités de type "multipart". Les délimiteurs de limites "multipart" et les champs d’en-tête sont toujours représentés sous la forme US-ASCII 7 bits (bien que les champs d’en-tête puissent coder un texte d’en-tête non US-ASCII conformément à la RFC 2047) et les données contenues dans les parties du corps peuvent être codées sur partie par partie, avec des champs Content-Transfer-Encoding pour chaque partie du corps appropriée.
Le champ Content-Type pour les entités en plusieurs parties nécessite un paramètre, "frontière". La ligne de délimiteur de frontière est alors définie comme une ligne composée entièrement de deux traits d'union ("-", valeur décimale 45), suivie de la valeur du paramètre de frontière du champ d'en-tête Content-Type, d'un espace blanc facultatif et d'un CRLF de fin.
Les délimiteurs de frontière ne doivent pas apparaître dans le texte encapsulé et ne doivent pas dépasser 70 caractères, sans compter les deux traits d'union.
La ligne de délimitation de la limite après la dernière partie du corps est un séparateur distingué 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 traits d'union après la valeur du paramètre border.
Voici un exemple utilisant une limite 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--
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 passé 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 requête Content-Type: multipart/form-data; frontière --- WebKit193844043-h ( valeur générée par le navigateur ).
La charge utile transmise 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--
Du côté du service Web, il est consommé sous la forme @Consumes ("multipart/form-data").
Attention, lors du test de votre service Web à l'aide de chrome postman, vous devez vérifier l'option de données de formulaire (bouton radio) et le menu Fichier du menu déroulant pour envoyer une pièce jointe. La fourniture explicite du type de contenu sous la forme multipart/form-data renvoie une erreur. Parce que border est manquant car il écrase la requête curl de post man to server avec content-type en ajoutant la limite qui fonctionne correctement.