Obtenir uniquement l'en-tête de réponse de HTTP POST en utilisant curl


561

On ne peut demander que les en-têtes en utilisant HTTP HEAD, en option -Idans curl(1).

$ curl -I /

Les longs corps de réponse HTML sont difficiles à obtenir en ligne de commande, donc je voudrais obtenir uniquement l'en-tête comme retour pour mes demandes POST. Cependant, HEAD et POST sont deux méthodes différentes.

Comment obtenir curl pour afficher uniquement les en-têtes de réponse à une demande POST?

Réponses:


773
-D, --dump-header <file>
       Write the protocol headers to the specified file.

       This  option  is handy to use when you want to store the headers
       that a HTTP site sends to you. Cookies from  the  headers  could
       then  be  read  in  a  second  curl  invocation by using the -b,
       --cookie option! The -c, --cookie-jar option is however a better
       way to store cookies.

et

-S, --show-error
       When used with -s, --silent, it makes curl show an error message if it fails.

et

-L/--location
      (HTTP/HTTPS) If the server reports that the requested page has moved to a different location (indicated with a Location: header and a 3XX response
      code), this option will make curl redo the request on the new place. If used together with -i/--include or -I/--head, headers from  all  requested
      pages  will  be  shown.  When authentication is used, curl only sends its credentials to the initial host. If a redirect takes curl to a different
      host, it won’t be able to intercept the user+password. See also --location-trusted on how to change this. You can limit the amount of redirects to
      follow by using the --max-redirs option.

      When curl follows a redirect and the request is not a plain GET (for example POST or PUT), it will do the following request with a GET if the HTTP
      response was 301, 302, or 303. If the response code was any other 3xx code, curl will re-send the following  request  using  the  same  unmodified
      method.

à partir de la page de manuel. donc

curl -sSL -D - www.acooke.org -o /dev/null

suit les redirections, vide les en-têtes sur stdout et envoie les données à / dev / null (c'est un GET, pas un POST, mais vous pouvez faire la même chose avec un POST - ajoutez simplement l'option que vous utilisez déjà pour le POST de données)

notez l' -after -Dqui indique que le "fichier" de sortie est stdout.


22
Le commentaire ci-dessus est valide si vous utilisez PowerShell. pour l'utilisation de cmd.execurl -s -D - http://yahoo.com -o nul
— JJS

1
@JJS pour moi $ null a travaillé sur Win7. Est-ce dû à cLink installé sur Windows.
— Satya Prakash

17
Le "-" devant l'URL peut sembler sans importance, mais ce n'est pas le cas.
— Wahid Sadik

1
@WahidSadik Pourquoi est-ce le cas en particulier? Quelle est la fonction du tiret unique?
— mamachanko

4
@mamachanko -Dprend un argument qui indique où la sortie doit aller. le tiret unique signifie qu'il devrait aller à la sortie standard.
— Andrew Cooke

172

Les autres réponses nécessitent le téléchargement du corps de réponse. Mais il existe un moyen de faire une requête POST qui ne récupérera que l'en-tête:

curl -s -I -X POST http://www.google.com

Un -Ipar lui-même effectue une requête HEAD qui peut être remplacée par -X POSTpour effectuer une requête POST (ou toute autre) et toujours obtenir uniquement les données d'en-tête.


15
Cette réponse est en fait correcte car les serveurs Web peuvent renvoyer différents en-têtes en fonction de la méthode de demande. Si vous souhaitez vérifier les en-têtes sur GET, vous devez utiliser la requête GET.
— chhantyal

6
C'est la réponse la plus correcte, à mon avis. Il est facile à retenir, il envoie en fait une GETrequête et ne télécharge pas le corps de la réponse dans son intégralité (ou du moins ne le génère pas). Le -sdrapeau n'est pas nécessaire.
— skozin

@JeffPuckettII, je dirais bien. Vous pouvez remplacer GETpar la POSTcommande ci-dessus et cela fonctionnera comme prévu. or any otherest la clé là-bas.
— chhantyal

18
Cela ne fonctionne pas lorsque vous souhaitez réellement POSTcertaines données. Curl dit:Warning: You can only select one HTTP request method! You asked for both POST Warning: (-d, --data) and HEAD (-I, --head).
— SebastianH

2
@nickboldt Le point ici est qu'un serveur peut répondre différemment à une demande HEAD qu'à une demande POST ou GET (et certains serveurs le font en fait), il -X HEADn'y a donc pas de solution fiable ici.
— siracusa

58

La commande suivante affiche des informations supplémentaires

curl -X POST http://httpbin.org/post -v > /dev/null

Vous pouvez demander au serveur d'envoyer uniquement HEAD, au lieu d'une réponse complète

curl -X HEAD -I http://httpbin.org/

Note:Dans certains cas, le serveur peut envoyer différents en-têtes pour la publication et HEAD. Mais dans presque tous les cas, les en-têtes sont identiques.


5
Il est regrettable que l'autre réponse ait gagné, car c'est la bonne réponse - elle ne transfère pas inutilement une tonne de données.
— Daniel

1
@dmd Si je comprends bien le manuel cURL -X, --request, cela -X HEADdonne quand même «une tonne de données» mais il y en a -I, --headqui devrait donner ce que vous attendez.
— Daniel AR Werner

1
Vous ne le comprenez pas correctement. -X HEADet -Isont exactement équivalents.
— Daniel

18
Le problème -X HEADest que le serveur peut répondre différemment, car il reçoit maintenant une HEADdemande au lieu d'une GET(ou quelle que soit la demande précédente)
— Grav

4
Warning: Setting custom HTTP method to HEAD with -X/--request may not work the Warning: way you want. Consider using -I/--head instead.
— Dorian

53

Pour les corps à réponse longue (et diverses autres situations similaires), la solution que j'utilise est toujours de diriger vers less, donc

curl -i https://api.github.com/users | less

ou

curl -s -D - https://api.github.com/users | less

fera le travail.


ce ne sont pas équivalents. le premier émet une HEADrequête à laquelle de nombreux serveurs répondent différemment. la seconde émet une GETdemande qui ressemble plus à ce que nous recherchons ici.
— glasz

25

C'est peut-être un peu extrême, mais j'utilise cette version super courte:

curl -svo. <URL>

Explication:

-v imprimer les informations de débogage (qui incluent les en-têtes)

-o.envoyer des données de page Web (que nous voulons ignorer) à un certain fichier, .dans ce cas, qui est un répertoire et est une destination non valide et rend la sortie à ignorer.

-spas de barre de progression, pas d'informations d'erreur (sinon vous verriez Warning: Failed to create the file .: Is a directory)

avertissement: le résultat échoue toujours (en termes de code d'erreur, s'il est accessible ou non). N'utilisez pas, par exemple, des instructions conditionnelles dans les scripts shell ...


1
Pourquoi utiliser -o.au lieu de -o /dev/null?
— bfontaine

@bfontaine -o.est utilisé par opposition -o /dev/nullà la brièveté
— exebook

il n'a pas le même comportement, il est donc étrange de ne l'utiliser que pour enregistrer 8 caractères.
— bfontaine

2
@bfontaine il y a d'autres réponses qui montrent comment le faire de la manière la plus correcte, celle-ci est ici pour montrer l'alternative courte qui fait la même chose fondamentalement.
— exebook

Vous devez préciser dans votre réponse que cette commande échoue toujours . curl -svo. <url> && echo foone sera pas imprimer fooparce que -o.faire curlretourner un code non nul (= erreur): curl: (23) Failed writing body.
— bfontaine


14

Bien que les autres réponses n'aient pas fonctionné pour moi dans toutes les situations, la meilleure solution que j'ai pu trouver (en travaillant POSTégalement), tirée d' ici :

curl -vs 'https://some-site.com' 1> /dev/null


1
J'ai dû mettre l'URL entre guillemets pour que cela fonctionne.
— Christophe Weis

1
Que cela soit nécessaire ou non peut dépendre de l'url et du shell utilisé. J'ai amélioré la réponse en conséquence. Merci.
— Daniel AR Werner

3

headcurl.cmd (version Windows)

curl -sSkv -o NUL %* 2>&1
  • Je ne veux pas de barre de progression -s,
  • mais je veux des erreurs -S,
  • ne se soucie pas des certificats https valides -k,
  • obtenir une grande verbosité -v(il s'agit de dépannage, n'est-ce pas?),
  • pas de sortie (d'une manière propre).
  • oh, et je veux transmettre stderr à stdout , donc je peux grep contre le tout (puisque la plupart ou la totalité de la sortie vient de stderr)
  • %*signifie [transmettre tous les paramètres à ce script] (enfin ( https://stackoverflow.com/a/980372/444255 ), eh bien généralement ce n'est qu'un paramètre: l'url que vous testez

exemple réel (sur la résolution des problèmes de proxy):

C:\depot>headcurl google.ch | grep -i -e http -e cache
Hostname was NOT found in DNS cache
GET HTTP://google.ch/ HTTP/1.1
HTTP/1.1 301 Moved Permanently
Location: http://www.google.ch/
Cache-Control: public, max-age=2592000
X-Cache: HIT from company.somewhere.ch
X-Cache-Lookup: HIT from company.somewhere.ch:1234

Version Linux

pour votre .bash_aliases/ .bash_rc:

alias headcurl='curl -sSkv -o /dev/null $@  2>&1'

Cela va télécharger le corps et consommer de la bande passante, du temps. La réponse de @siracusa ( stackoverflow.com/a/38679650/6168139 ) n'a pas cette surcharge.
— rushi

Si et quand vous voulez POST, ajoutez -X POSTaux paramètres passthrough, si vous voulez GET, utilisez GET (c'est-à-dire par défaut), car les réponses peuvent différer. - À moins que vous ne fassiez de gros curling dans les scripts de production (pas pour le diagnostic et le développement), je me fiche d'un peu de bande passante.
— Frank Nocke

Je prévois de voir si les fichiers sur le serveur sont mis à jour ou n'utilisent pas «Last-Modified». Les fichiers en eux-mêmes sont volumineux, certains sont en Go, et je suis généralement sur Internet cellulaire. Donc, cette large bande passante est un problème pour moi.
— rushi

Ce serait hacky . Je n'ai pas besoin de le faire car la réponse de siracusa accomplit la tâche avec précision.
— rushi
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.