2009-04-20 69 views
21

我有一个简单的代码,它为URL做头部请求,然后打印响应头。我注意到在某些网站上,这可能需要很长时间才能完成。PHP/Curl: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

缺什么_curl_是响应主体,它不知道HEAD请求只返回头(无体),所以它等待服务器来发送更多的数据。所以卷曲等待2分钟,然后放弃。 – Jasen 2014-07-31 22:16:35

回答

41

尝试简化它一点点:

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

上述输出立即在我的网络服务器。如果它不在您的网站上,您的虚拟主机有一定的设置来限制这些请求。

编辑

由于上述瞬间发生了你,试试你原来的代码中设置this curl setting

curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true); 

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

第二个编辑

奇怪的是,想你在上面做了我的web服务器挂过多相同的代码。我换成这样的代码:

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

有了这个:

curl_setopt($ch, CURLOPT_NOBODY, true); 

哪条路是the manual建议你做一个HEAD请求。它使它立即工作。

+0

立即输出www.arstechnica.com的html代码。 – Ian 2009-04-20 21:37:21

+0

不幸的是,没有改变。 – Ian 2009-04-20 21:46:12

+0

我试图只检索第一页的响应标题,而不是任何更进一步的下线。 – Ian 2009-04-20 21:48:06

2

如果我的记忆没有失败,我在做卷曲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); 
6

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

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

0

此:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 

我没有试图让头。
我只是想让一些数据的页面加载不像上面描述的那样花费2分钟。
这个神奇的小选项已经下降到2秒。