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

时间:2009-04-20 21:29:51

标签: php curl http-headers header performance

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

例如,请求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,但上面链接中的服务会立即返回。

我错过了什么?

5 个答案:

答案 0 :(得分:43)

尝试简化一下:

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

以上输出立即在我的网络服务器上。如果它不在您的网站上,那么您的网站主机很可能会采用某种设置来限制这些请求。

修改

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

curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);

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

第二次编辑

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

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

有了这个:

curl_setopt($ch, CURLOPT_NOBODY, true);

the manual建议您执行HEAD请求的方式。它使它立即发挥作用。

答案 1 :(得分:7)

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

我遇到了一家财富100强公司的应用程序,用于下载数百兆的定价信息。我们通过定期执行HEAD请求来检查对该数据的更新,直到修改日期发生变化。事实证明,这个请求实际上会在每次我们发出请求时生成此列表的结束调用,这些请求在其后端包含数十亿字节的数据,并且在几个内部服务器之间发送数据。他们对我们并不十分满意,但是一旦我们解释了用例,他们很快就提出了另一种解决方案。如果他们已经实施了HEAD,而不是依靠他们的网络服务器伪造它,那就不会是一个问题。

答案 2 :(得分:4)

如果我的内存没有失败,我在CURL中执行HEAD请求会将HTTP协议版本更改为1.0(这很慢,可能是这里的罪恶部分)尝试将其更改为:

$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'
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); // ADD THIS

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

答案 3 :(得分:3)

我使用以下函数找出重定向的网址。

$head = get_headers($url, 1);

第二个参数使它返回一个带键的数组。对于例如以下将给出Location值。

$head["Location"]

http://php.net/manual/en/function.get-headers.php

答案 4 :(得分:0)

此:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

我并没有试图获得标题 我只是试图让一些数据的页面加载不需要2分钟,如上所述 那些神奇的小选项让它降到了2秒。