25

我有一个简单的代码,它对 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,但上面链接中的服务会立即返回它。

我错过了什么?

4

5 回答 5

48

尝试简化一点:

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

以上输出立即在我的网络服务器上。如果它不在您的范围内,那么您的虚拟主机很有可能进行了某种设置来限制此类请求。

编辑

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

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);

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

于 2009-04-20T21:35:48.307 回答
8

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

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

于 2009-04-20T22:11:52.950 回答
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);
于 2009-04-20T21:41:42.087 回答
3

我使用下面的函数来找出重定向的 URL。

$head = get_headers($url, 1);

第二个参数使它返回一个带有键的数组。例如,下面将给出Location值。

$head["Location"]

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

于 2011-07-23T12:47:16.087 回答
0

这:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

我不是想得到标题。
我只是想让一些数据的页面加载不需要 2 分钟,类似于上面描述的。
那个神奇的小选项已经把它降到了 2 秒。

于 2011-03-01T17:53:57.313 回答