我有一个简单的代码,可以对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,但上面链接中的服务会立即返回。
我错过了什么?
答案 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"]
答案 4 :(得分:0)
此:
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
我并没有试图获得标题 我只是试图让一些数据的页面加载不需要2分钟,如上所述 那些神奇的小选项让它降到了2秒。