PHP / Curl:在某些站点上,HEAD请求需要很长时间

2022-08-30 16:58:43

我有一个简单的代码,它对URL执行head请求,然后打印响应标头。我注意到,在某些网站上,这可能需要很长时间才能完成。

例如,请求大约需要两分钟。我使用执行相同基本任务的另一个网站尝试了相同的请求,并立即返回。因此,一定是我设置不正确的东西导致了这种延迟。http://www.arstechnica.com

这是我的代码:

$ch = curl_init();
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

$content = curl_exec ($ch);
curl_close ($ch);

下面是一个指向执行相同功能的网站的链接:http://www.seoconsultants.com/tools/headers.asp

上面的代码,至少在我的服务器上,需要两分钟来检索 www.arstechnica.com,但上面链接中的服务会立即返回它。

我错过了什么?


答案 1

试着简化一下:

print htmlentities(file_get_contents("http://www.arstechnica.com"));

上述内容立即在我的Web服务器上输出。如果它不在你的身上,那么你的Web主机很有可能有某种设置来限制这些类型的请求。

编辑

由于上述情况会立即发生,请尝试在原始代码上设置此 curl 设置

curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);

使用您发布的工具,我注意到为发送给它的任何请求发送了一个301标头。cURL 可能正在获取此内容,但没有遵循为其指定的新位置,从而导致脚本挂起。http://www.arstechnica.com

第二次编辑

奇怪的是,尝试上面相同的代码也使我的Web服务器挂起。我替换了这段代码:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

有了这个:

curl_setopt($ch, CURLOPT_NOBODY, true);

这是手册建议您执行 HEAD 请求的方式。它使它立即工作。


答案 2

您必须记住,HEAD只是对Web服务器的建议。对于HEAD来说,要做正确的事情,通常需要管理员付出一些明确的努力。如果你的头部是一个静态文件,Apache(或者你的网络服务器是什么)通常会介入做正确的事情。如果以动态页面为 HEAD,则大多数设置的默认设置是执行 GET 路径,收集所有结果,然后只发回没有内容的标头。如果该应用程序位于 3 层(或更多)层设置中,则该调用对于 HEAD 上下文可能非常昂贵且无需。例如,在Java servlet上,默认情况下doHead()只调用doGet()。要为应用程序做一些更聪明的事情,开发人员必须显式实现doHead()(而且通常情况下,他们不会)。

我遇到了一个来自财富100强公司的应用程序,该应用程序用于下载数百兆字节的定价信息。我们会通过相当定期地执行HEAD请求来检查该数据的更新,直到修改日期更改为止。事实证明,每次我们发出涉及其后端数据的请求并在多个内部服务器之间xfer之间xfer时,此请求实际上都会进行后端调用以生成此列表。他们对我们不是很满意,但是一旦我们解释了用例,他们很快就想出了替代解决方案。如果他们实施了HEAD,而不是依靠他们的Web服务器来伪造它,那将不是一个问题。


推荐