web-dev-qa-db-fra.com

Comment les paramètres sont-ils envoyés dans une requête HTTP POST?

Dans une requête HTTP GET, les paramètres sont envoyés sous la forme d'une chaîne de requête :

http://example.com/page? paramètre = valeur & aussi = un autre

Dans une requête HTTP POST, les paramètres ne sont pas envoyés avec l'URI.

Où sont les valeurs? Dans l'en-tête de la demande? Dans le corps de la demande? À quoi cela ressemble-t-il?

1357
Camilo Martin

Les valeurs sont envoyées dans le corps de la demande, dans le format spécifié par le type de contenu.

Le type de contenu est généralement application/x-www-form-urlencoded, le corps de la demande utilise donc le même format que la chaîne de requête:

parameter=value&also=another

Lorsque vous utilisez un fichier téléchargé dans le formulaire, vous utilisez plutôt le codage multipart/form-data, qui a un format différent. C'est plus compliqué, mais vous n'avez généralement pas besoin de vous soucier de son apparence. Je ne vais donc pas donner d'exemple, mais il peut être bon de savoir qu'il existe.

1151
Guffa

Le contenu est placé après les en-têtes HTTP. Le format d'un HTTP POST doit comporter les en-têtes HTTP, suivis d'une ligne vierge, suivis du corps de la demande. Les variables POST sont stockées sous forme de paires clé-valeur dans le corps.

Vous pouvez le voir dans le contenu brut d'un message HTTP, illustré ci-dessous:

POST /path/script.cgi HTTP/1.0
From: [email protected]
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

home=Cosby&favorite+flavor=flies

Vous pouvez le voir à l'aide d'un outil tel que Fiddler , que vous pouvez utiliser pour surveiller les charges utiles brutes de demandes et de réponses HTTP envoyées sur le réseau.

406
Joe Alfano

Réponse courte: dans POST demandes, les valeurs sont envoyées dans le "corps" de la demande. Avec les formulaires Web, ils sont généralement envoyés avec un type de support application/x-www-form-urlencoded ou multipart/form-data. Les langages de programmation ou les frameworks conçus pour traiter les requêtes Web font généralement "The Right Thing ™" avec de telles requêtes et vous permettent d'accéder facilement aux valeurs facilement décodées (comme $_REQUEST ou $_POST en PHP , ou cgi.FieldStorage(), flask.request.form en Python).


Écartons maintenant un peu, ce qui peut aider à comprendre la différence;)

La différence entre GET et POST requêtes est en grande partie sémantique. Ils sont également "utilisés" différemment, ce qui explique la différence dans la manière dont les valeurs sont transmises.

GET ( section RFC pertinente )

Lors de l'exécution d'une requête GET, vous en demandez une au serveur ou un ensemble d'entités. Pour permettre au client de filtrer le résultat, il peut utiliser la "chaîne de requête" de l'URL. La chaîne de requête est la partie après le ?. Cela fait partie de syntaxe URI .

Ainsi, du point de vue de votre code d'application (la partie qui reçoit ​​la requête), vous devrez inspecter la partie de requête URI pour accéder à ces valeurs.

Notez que les clés et les valeurs font partie de l'URI. Navigateurs peut ​​imposer une limite de longueur d’URI. La norme HTTP stipule qu'il n'y a pas de limite. Mais au moment d'écrire ces lignes, la plupart des navigateurs do limitent les URI (je n'ai pas de valeurs spécifiques). GET les requêtes doivent never être utilisées pour soumettre de nouvelles informations au serveur. Surtout pas les gros documents. C'est là que vous devriez utiliser POST ou PUT.

POST ( section RFC pertinente )

Lors de l'exécution d'une requête POST, le client est en train de soumettre un nouveau document ​​à l'hôte distant. Ainsi, une chaîne query n'a pas de sens (sémantique). C'est pourquoi vous n'y avez pas accès dans votre code d'application.

POST est un peu plus complexe (et way plus flexible):

Lors de la réception d'une demande POST, vous devez toujours vous attendre à une "charge utile" ou, en termes HTTP, à un corps du message . Le corps du message en lui-même est plutôt inutile, car il n'y a pas de format standard (autant que je sache. Peut-être application/octet-stream?). Le format du corps est défini par l'en-tête Content-Type. Lors de l'utilisation d'un élément HTML FORM avec method="POST", il s'agit généralement de application/x-www-form-urlencoded. Un autre type très courant est multipart/form-data si vous utilisez le téléchargement de fichiers. Mais cela pourrait être n'importe quoi, allant de text/plain à application/json ou même à un application/octet-stream personnalisé.

Dans tous les cas, si une demande POST est faite avec un Content-Type qui ne peut pas être traité par l'application, elle devrait renvoyer un 415 status-code .

La plupart des langages de programmation (et/ou d'infrastructure Web) offrent un moyen de décoder/coder le corps du message depuis/vers les types les plus courants (comme application/x-www-form-urlencoded, multipart/form-data ou application/json). Donc c'est facile. Les types personnalisés nécessitent potentiellement un peu plus de travail.

À l'aide d'un document codé au format HTML standard, par exemple, l'application doit effectuer les étapes suivantes:

  1. Lire le champ Content-Type
  2. Si la valeur ne fait pas partie des types de support pris en charge, retournez une réponse avec un code de statut 415.
  3. sinon, décodez les valeurs du corps du message.

Encore une fois, des langages comme PHP ou des frameworks Web pour d’autres langages populaires se chargeront probablement de cela. L'exception à ceci est l'erreur 415. Aucune infrastructure ne peut prédire quels types de contenu votre application choisira de prendre en charge et/ou ne prend pas en charge. C'est toi qui vois.

PUT ( section RFC pertinente )

Une demande PUT est quasiment gérée exactement de la même manière qu'une demande POST. La grande différence est qu’une requête POST est supposée laisser le serveur décider de la manière (et du tout) de créer une nouvelle ressource. Historiquement (à partir de la RFC2616, désormais obsolète, il s'agissait de créer une nouvelle ressource en tant que "subordonné" (enfant) de l'URI auquel la demande a été envoyée).

Une demande PUT au contraire est supposée "déposer" une ressource exactement à cet URI, et avec exactement ​​ce contenu. Ni plus ni moins. L'idée est que le client ​​est chargé de concevoir la ressource complète avant de la "placer". Le serveur doit l'accepter tel quel sur l'URL donnée.

En conséquence, une demande POST n'est généralement pas utilisée pour remplacer une ressource existante. Une requête PUT peut créer à la fois et ​​remplacer.

Note latérale

Il existe également des " paramètres de chemin " qui peuvent être utilisés pour envoyer des données supplémentaires à la télécommande, mais ils sont si rares que je ne vais pas entrer dans les détails ici. Mais, pour référence, voici un extrait de la RFC:

Outre les segments de points dans les chemins hiérarchiques, un segment de chemin est considéré comme opaque par la syntaxe générique. Les applications produisant des URI utilisent souvent les caractères réservés autorisés dans un segment pour délimiter des sous-composants spécifiques à un schéma ou à un gestionnaire de référence. Par exemple, les caractères réservés point-virgule (";") et égal à ("=") sont souvent utilisés pour délimiter les paramètres et les valeurs de paramètre applicables à ce segment. Le caractère réservé virgule (",") est souvent utilisé à des fins similaires. Par exemple, un producteur d'URI peut utiliser un segment tel que "nom; v = 1.1" pour indiquer une référence à la version 1.1 de "nom", tandis qu'un autre peut utiliser un segment tel que "nom, 1.1" pour l'indiquer. Les types de paramètres peuvent être définis par une sémantique spécifique au schéma, mais dans la plupart des cas, la syntaxe d'un paramètre est spécifique à la mise en œuvre de l'algorithme de déréférencement des URI.

344
exhuma

Vous ne pouvez pas le saisir directement dans la barre d’URL du navigateur.

Vous pouvez voir comment POST des données sont envoyées sur Internet avec En-têtes HTTP en direct , par exemple. Le résultat sera quelque chose comme ça

http://127.0.0.1/pass.php
POST /pass.php HTTP/1.1

Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://127.0.0.1/pass.php
Cookie: passx=87e8af376bc9d9bfec2c7c0193e6af70; PHPSESSID=l9hk7mfh0ppqecg8gialak6gt5
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
username=zurfyx&pass=password

Où il est dit

Content-Length: 30
    username=zurfyx&pass=password

seront les valeurs de poste.

56
zurfyx

Le type de support par défaut dans une demande POST est application/x-www-form-urlencoded. C'est un format d'encodage des paires clé-valeur. Les clés peuvent être dupliquées. Chaque paire clé-valeur est séparée par un caractère & et chaque clé est séparée de sa valeur par un caractère =.

Par exemple:

Name: John Smith
Grade: 19

Est codé comme:

Name=John+Smith&Grade=19

Ceci est placé dans le corps de la requête après les en-têtes HTTP.

22
Nejat

Certains services Web nécessitent que vous placiez des métadonnées de demande et séparément. Par exemple, une fonction distante peut s'attendre à ce que la chaîne de métadonnées signée soit incluse dans un URI, tandis que les données sont publiées dans un corps HTTP.

La demande POST peut ressembler sémantiquement à ceci:

POST /?AuthId=YOURKEY&Action=WebServiceAction&Signature=rcLXfkPldrYm04 HTTP/1.1
Content-Type: text/tab-separated-values; charset=iso-8859-1
Content-Length: []
Host: webservices.domain.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)

name    id
John    G12N
Sarah   J87M
Bob     N33Y

Cette approche combine logiquement QueryString et Body-Post en utilisant un seul Content-Type, qui est une "instruction d'analyse" pour un serveur Web.

Remarque: HTTP/1.1 est enveloppé avec le #32 (espace) à gauche et avec #10 (saut de ligne) à droite.

17
Interface Unknown

Les valeurs de formulaire dans HTTP POST sont envoyées dans le corps de la demande, au même format que la chaîne de requête.

Pour plus d'informations, voir spec .

16
SLaks

Tout d’abord, distinguons GET et POST

Get: Il s’agit de la demande HTTP par défaut adressée au serveur et utilisée pour extraire les données du serveur et la chaîne de requête qui vient après ? dans un URI est utilisé pour récupérer une ressource unique.

c'est le format

GET /someweb.asp?data=value HTTP/1.0

ici data=value est la valeur de la chaîne de requête transmise.

POST: Il est utilisé pour envoyer des données au serveur en toute sécurité donc tout ce qui est nécessaire, c'est le format d'une requête POST

POST /somweb.aspHTTP/1.0
Host: localhost
Content-Type: application/x-www-form-urlencoded //you can put any format here
Content-Length: 11 //it depends
Name= somename

Pourquoi POST sur GET?

Dans GET, la valeur envoyée aux serveurs est généralement ajoutée à l'URL de base dans la chaîne de requête. Cela permet de pirater vos données (ce problème remontait à l'époque où Facebook avait mis vos informations d'identification). C’est pourquoi POST est utilisé pour envoyer des données au serveur qui a utilisé Request Body pour envoyer vos données au serveur. Ce dernier est plus sécurisé car il masque vos données et il récupère vos données à partir des champs et ajoutez-les à la header pour content-length et aucune donnée importante n'est directement ajoutée à la URL

maintenant que votre demande est sécurisée, toutes les valeurs envoyées au serveur peuvent être envoyées au Request Body comme son nom l'indique, il contiendra les données que l'utilisateur voulait envoyer (et Il est envoyé au format URL Encoded ) et le Request Headers gardera la demande sécurisée en comparant les valeurs du Request Body avec le Request Headers

Vous pouvez utiliser la section Réseau de Google Outils de développement pour afficher des informations de base sur la manière dont les demandes sont adressées aux serveurs.

et vous pouvez toujours ajouter plus de valeurs dans votre Request Headers comme Cache-Control, Origin, Accept.

6
Zeeshan Adil