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.