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?

Jonathan Allard
la source

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.

Andrew Cooke
la source
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.

siracusa
la source
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.

zainengineer
la source
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.

fiatjaf
la source
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 ...

exebook
la source
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
16

Beaucoup plus facile - c'est ce que j'utilise pour éviter le suivi Shortlink - est le suivant:

curl -IL http://bit.ly/in-the-shadows

… Qui suit également des liens .

kaiser
la source
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

Daniel AR Werner
la source
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'
Frank Nocke
la source
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