Obtendo apenas o cabeçalho de resposta do HTTP POST usando curl

561

Pode-se solicitar apenas os cabeçalhos usando HTTP HEAD, como opção -Iem curl(1).

$ curl -I /

Corpos de resposta HTML demorados são um problema para entrar na linha de comando; portanto, gostaria de obter apenas o cabeçalho como feedback para minhas solicitações POST. No entanto, HEAD e POST são dois métodos diferentes.

Como faço para que o curl exiba apenas cabeçalhos de resposta a uma solicitação POST?

Jonathan Allard
fonte

Respostas:

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.

e

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

e

-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.

da página do manual. tão

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

segue redirecionamentos, despeja os cabeçalhos para stdout e envia os dados para / dev / null (isso é um GET, não um POST, mas você pode fazer a mesma coisa com um POST - basta adicionar qualquer opção que você já esteja usando para os dados do POST)

observe o -depois do -Dque indica que o "arquivo" de saída é stdout.

andrew cooke
fonte
22
o comentário acima é válido se você estiver usando o PowerShell. para uso do cmd.execurl -s -D - http://yahoo.com -o nul
JJS 15/07
1
@JJS para mim $ null trabalhou no Win7. É devido ao cLink instalado no Windows.
Satya Prakash
17
O "-" na frente do URL pode parecer sem importância, mas não é.
Wahid Sadik
1
@WahidSadik Por que esse é o caso em particular? Qual é a função do traço único?
mamachanko
4
@mamachanko -Dusa um argumento que diz para onde a saída deve ir. o traço único significa que ele deve ir para o stdout.
Andrew Cooke
172

As outras respostas exigem que o corpo da resposta seja baixado. Mas há uma maneira de fazer uma solicitação POST que somente buscará o cabeçalho:

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

Um, -Ipor si só, executa uma solicitação HEAD que pode ser substituída por -X POSTpara executar uma solicitação POST (ou qualquer outra) e ainda assim obter apenas os dados do cabeçalho.

siracusa
fonte
15
Esta resposta está realmente correta porque os servidores da Web podem retornar cabeçalhos diferentes com base no método de solicitação. Se você deseja verificar os cabeçalhos no GET, é necessário usar a solicitação GET.
precisa saber é o seguinte
6
Esta é a resposta mais correta, na minha opinião. É fácil lembrar, ele realmente envia uma GETsolicitação e não baixa o corpo inteiro da resposta (ou pelo menos não gera). A -sbandeira não é necessária.
Skokin # 11/16
@JeffPuckettII bem, tipo nitpicking, eu diria. Você pode substituir GETpelo POSTcomando acima e ele funcionará conforme o esperado. or any otheré a chave aqui.
chhantyal
18
Isso não funciona quando você realmente deseja POSTalguns dados. Curl diz:Warning: You can only select one HTTP request method! You asked for both POST Warning: (-d, --data) and HEAD (-I, --head).
SebastianH
2
@nickboldt O ponto aqui é que um servidor pode responder de maneira diferente a uma solicitação HEAD do que a uma solicitação POST ou GET (e alguns servidores realmente fazem isso), portanto, -X HEADnão há solução confiável aqui.
112617 siracusa
58

O comando a seguir exibe informações extras

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

Você pode pedir ao servidor para enviar apenas HEAD, em vez de resposta completa

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

Note:Em alguns casos, o servidor pode enviar cabeçalhos diferentes para postagem e HEAD. Mas em quase todos os casos, os cabeçalhos são iguais.

zainengineer
fonte
5
É lamentável que a outra resposta tenha ganhado, porque esta é a resposta correta - ela não transfere desnecessariamente uma tonelada de dados.
Daniel
1
@dmd Se eu entendi o manual cURL -X, --requestcorretamente, -X HEADainda resulta em "uma tonelada de dados", mas existe o -I, --headque deve resultar no que você está antecipando.
Daniel AR Werner
1
Você não o entende corretamente. -X HEADe -Isão exatamente equivalentes.
Daniel
18
Problema com -X HEADé que o servidor pode responder de forma diferente, uma vez que agora recebe um HEADpedido em vez de um GET(ou qualquer que seja o pedido anterior era)
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

Para corpos de resposta longos (e várias outras situações semelhantes), a solução que eu uso é sempre canalizar less, então

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

ou

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

fará o trabalho.

fiatjaf
fonte
estes não são equivalentes. o primeiro emite uma HEADsolicitação à qual muitos servidores respondem de maneira diferente. o segundo emite um GETpedido mais parecido com o que estamos procurando aqui.
glasz
25

Talvez seja um pouco extremo, mas estou usando esta versão super curta:

curl -svo. <URL>

Explicação:

-v imprimir informações de depuração (que incluem cabeçalhos)

-o.envie dados da página da web (que queremos ignorar) para um determinado arquivo, .neste caso, que é um diretório e é um destino inválido e faz com que a saída seja ignorada.

-snenhuma barra de progresso, nenhuma informação de erro (caso contrário, você veria Warning: Failed to create the file .: Is a directory)

aviso: o resultado sempre falha (em termos de código de erro, se acessível ou não). Não use, digamos, instruções condicionais em scripts de shell ...

exebook
fonte
1
Por que usar em -o.vez de -o /dev/null?
bfontaine
@bfontaine -o.é usado versus -o /dev/nullpor brevidade
exebook 14/07/19
ele não tem o mesmo comportamento, por isso é estranho usá-lo apenas para salvar 8 caracteres.
bfontaine
2
@ bfontaine existem outras respostas que mostram como fazer isso da maneira mais correta, esta aqui para mostrar a alternativa curta que faz a mesma coisa basicamente.
exebook 19/07/19
Você deve esclarecer em sua resposta que esse comando sempre falha. curl -svo. <url> && echo foonão será impresso fooporque -o.fazer curlretornar um código diferente de zero (= erro): curl: (23) Failed writing body.
bfontaine
16

Muito mais fácil - é o que eu uso para evitar o rastreamento de links curtos - é o seguinte:

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

… Que também segue os links .

kaiser
fonte
14

Enquanto as outras respostas não funcionaram para mim em todas as situações, a melhor solução que pude encontrar (trabalhando POSTtambém), tirada daqui :

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

Daniel AR Werner
fonte
1
Eu tive que colocar o URL entre aspas para fazer isso funcionar.
Christophe Weis
1
Se isso é necessário ou não, pode depender do URL e do shell usado. Eu melhorei a resposta de acordo. Obrigado.
Daniel AR Werner
3

headcurl.cmd (versão para Windows)

curl -sSkv -o NUL %* 2>&1
  • Eu não quero uma barra de progresso -s,
  • mas eu quero erros -S,
  • não se preocupando com certificados https válidos -k,
  • obtendo alta verbosidade -v(trata-se de solucionar problemas, não é?),
  • sem saída (de maneira limpa).
  • ah, e eu quero encaminhar stderr para stdout , para que eu possa fazer grep contra a coisa toda (já que a maioria ou toda a saída vem no stderr)
  • %*significa [passar todos os parâmetros para esse script] (bem ( https://stackoverflow.com/a/980372/444255 ), normalmente esse é apenas um parâmetro: o URL que você está testando

exemplo do mundo real (na solução de problemas 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

Versão Linux

para o seu .bash_aliases/ .bash_rc:

alias headcurl='curl -sSkv -o /dev/null $@  2>&1'
Frank Nocke
fonte
Isso fará o download do corpo e consumirá largura de banda, tempo. A resposta de @siracusa ( stackoverflow.com/a/38679650/6168139 ) não tem essa sobrecarga.
rushi 2/12/19
Se & quando você quiser POST, adicione -X POSTaos parâmetros de passagem, se quiser GET, use GET (ou seja, padrão), pois as respostas podem ser diferentes. - A menos que você faça curling pesado em scripts de produção (não para diagnóstico e desenvolvimento), não me importo com um pouco de largura de banda.
Frank Nocke
Estou planejando verificar se os arquivos no servidor estão atualizados ou não estão usando 'Last-Modified'. Os arquivos em si são grandes, alguns estão em GBs e eu geralmente estou na Internet celular. Portanto, essa grande largura de banda é um problema para mim.
rushi 2/12/19
Isso seria hacky . Não preciso fazer isso, pois a resposta da siracusa executa a tarefa com precisão.
rushi 17/01