使用 cURL 仅从 HTTP POST 获取响应标头

Posted

技术标签:

【中文标题】使用 cURL 仅从 HTTP POST 获取响应标头【英文标题】:Getting only response header from HTTP POST using cURL 【发布时间】:2012-04-21 01:15:08 【问题描述】:

只能使用 HTTP HEAD 请求标头,作为 curl(1) 中的选项 -I

$ curl -I /

冗长的 html 响应正文很难在命令行中使用,因此我只想获取标头作为我的 POST 请求的反馈。但是,HEAD 和 POST 是两种不同的方法。

如何让 cURL 仅显示 POST 请求的响应标头?

【问题讨论】:

【参考方案1】:

以下命令显示额外信息

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

您可以要求服务器仅发送 HEAD,而不是完整响应

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

Note: 在某些情况下,服务器可能会为 POST 和 HEAD 发送不同的标头。但在几乎所有情况下,标题都是相同的。

【讨论】:

很遗憾,另一个答案获胜了,因为这是正确答案 - 它不会不必要地传输大量数据。 @dmd 如果我正确理解了 -X, --request 的 cURL 手册,-X HEAD 仍然会产生“大量数据”,但 -I, --head 应该会产生您所期待的结果。 你没有正确理解。 -X HEAD-I 完全相同。 -X HEAD 的问题是服务器可能会做出不同的响应,因为它现在收到的是 HEAD 请求而不是 GET(或之前的任何请求) Warning: Setting custom HTTP method to HEAD with -X/--request may not work the Warning: way you want. Consider using -I/--head instead.【参考方案2】:

headcurl.cmd(Windows 版)

curl -sSkv -o NUL %* 2>&1
我不要进度条-s, 但我确实想要错误-S, 不关心有效的https证书-k, 越来越冗长-v(这是关于故障排除,是吗?), 没有输出(以干净的方式)。 哦,我想forward stderr to stdout,所以我可以对整个事情进行grep(因为大多数或所有输出都来自stderr) %* 表示[将所有参数传递给此脚本](嗯(https://***.com/a/980372/444255),通常这只是一个参数:您正在测试的网址

真实示例(关于解决代理问题):

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

Linux 版本

为您的.bash_aliases / .bash_rc

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

【讨论】:

这将下载正文并消耗带宽、时间。 @siracusa 的回答 (***.com/a/38679650/6168139) 没有这个开销。 如果 & 当你想要 POST 时,将 -X POST 添加到传递参数,如果你想要 GET,使用 GET(即默认值),因为响应可能会有所不同。 - 除非您在生产脚本中进行大量卷曲(不是用于诊断和开发),否则我不关心一点带宽。 我计划查看服务器上的文件是否已更新或未使用“Last-Modified”。文件本身很大,有些以 GB 为单位,我通常在蜂窝互联网上。所以,这么大的带宽对我来说是个问题。 那将是 hacky。我不需要这样做,因为锡拉库萨的answer 可以准确地执行任务。【参考方案3】:

也许有点极端,但我用的是这个超短版:

curl -svo. <URL>

解释:

-v 打印调试信息(包括标题)

-o. 将网页数据(我们想忽略)发送到某个文件,在本例中为 .,这是一个目录,并且是一个无效的目的地,并且会导致输出被忽略。

-s没有进度条,没有错误信息(否则你会看到Warning: Failed to create the file .: Is a directory

警告: 结果总是失败(就错误代码而言,无论是否可达)。不要在 shell 脚本中的条件语句中使用...

【讨论】:

为什么使用-o. 而不是-o /dev/null @bfontaine -o. 用于与-o /dev/null 简洁起见 它没有相同的行为,所以只使用它来保存 8 个字符很奇怪。 @bfontaine 还有其他答案展示了如何以最正确的方式做到这一点,这个是为了展示基本上做同样事情的简短替代方案。 您应该在回答中说明此命令 always 失败。 curl -svo. &lt;url&gt; &amp;&amp; echo foo 不会打印 foo 因为 -o. 使 curl 返回一个非零(=错误)代码:curl: (23) Failed writing body【参考方案4】:
-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.

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

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

来自手册页。所以

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

遵循重定向,将标头转储到标准输出并将数据发送到 /dev/null(这是 GET,而不是 POST,但您可以使用 POST 执行相同的操作 - 只需添加您已经使用的任何选项发布数据)

注意-D 后面的-,表示输出“文件”是标准输出。

【讨论】:

如果您使用的是 powershell,上述评论是有效的。对于 cmd.exe 使用 curl -s -D - http://yahoo.com -o nul @JJS 对我来说 $null 在 Win7 上工作。是不是因为windows上安装了cLink? URL 前面的“-”可能看起来不重要,但事实并非如此。 @WahidSadik 为什么是这种情况?单破折号的作用是什么? @mamachanko -D 接受一个参数来说明输出应该去哪里。单破折号表示它应该转到标准输出。【参考方案5】:

虽然其他答案在所有情况下都不适用于我,但我能找到的最佳解决方案(也与 POST 一起工作)取自 here:

curl -vs 'https://some-site.com' 1&gt; /dev/null

【讨论】:

我必须将网址放在引号之间才能正常工作。 这是否必要可能取决于 url 和使用的 shell。我相应地改进了答案。谢谢。【参考方案6】:

其他答案需要下载响应正文。但是有一种方法可以发出只会获取标头的 POST 请求:

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

-I 本身执行 HEAD 请求,-X POST 可以覆盖该请求以执行 POST(或任何其他)请求,但仍只能获取标头数据。

【讨论】:

这个答案实际上是正确的,因为 Web 服务器可以根据请求方法返回不同的标头。如果要在 GET 上检查标头,则必须使用 GET 请求。 在我看来,这是最正确的答案。很容易记住,它实际上发送GET 请求并且不下载整个响应体(或者至少不输出它)。 -s 标志也不是必需的。 @JeffPuckettII 我会说有点吹毛求疵。您可以在上述命令中将GET 替换为POST,它将按预期工作。 or any other 是关键。 这在你真正想要POST 一些数据时不起作用。卷毛说:Warning: You can only select one HTTP request method! You asked for both POST Warning: (-d, --data) and HEAD (-I, --head). @nickboldt 这里的重点是,服务器对 HEAD 请求的响应可能与对 POST 或 GET 请求的响应不同(有些服务器实际上是这样做的),因此-X HEAD 在这里不是可靠的解决方案。 【参考方案7】:

更容易——这是我对avoid Shortlink tracking 使用的方式——如下:

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

…它也跟随链接

【讨论】:

【参考方案8】:

对于长响应体(以及各种其他类似情况),我使用的解决方案始终是通过管道传输到less,所以

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

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

会做的。

【讨论】:

这些是等效的。第一个发出HEAD 请求,许多服务器对它的响应不同。第二个发出GET 请求,这更像是我们在这里寻找的。​​span>

以上是关于使用 cURL 仅从 HTTP POST 获取响应标头的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 wininet 获取 POST 请求响应

Angular JS - 无法使用 $http.post 接收任何响应

从 PHP Curl 获取 POST Zapier webhook 响应

在 Python 中检索 JSON 以响应 POST

执行 HTTP POST 并使用响应的简单 C 示例

php怎么响应客户端发送http请求