【问题标题】:get_headers Inconsistency [closed]get_headers 不一致[关闭]
【发布时间】:2012-09-28 16:59:22
【问题描述】:

运行以下代码

var_dump(get_headers("http://www.domainnnnnnnnnnnnnnnnnnnnnnnnnnnn.com/CraxyFile.jpg"));

对于任何不存在的域或 URL,返回 HTTP 200 而不是 404

Array
(
    [0] => HTTP/1.1 200 OK
    [1] => Server: nginx/1.1.15
    [2] => Date: Mon, 08 Oct 2012 12:29:13 GMT
    [3] => Content-Type: text/html; charset=utf-8
    [4] => Connection: close
    [5] => Set-Cookie: PHPSESSID=3iucojet7bt2peub72rgo0iu21; path=/; HttpOnly
    [6] => Expires: Thu, 19 Nov 1981 08:52:00 GMT
    [7] => Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    [8] => Pragma: no-cache
    [9] => Set-Cookie: bypassStaticCache=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; httponly
    [10] => Set-Cookie: bypassStaticCache=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; httponly
    [11] => Vary: Accept
)

如果你跑步

var_dump(get_headers("http://www.domain.com/CraxyFile.jpg"));

你得到

Array
(
    [0] => HTTP/1.1 404 Not Found
    [1] => Date: Mon, 08 Oct 2012 12:32:18 GMT
    [2] => Content-Type: text/html
    [3] => Content-Length: 8727
    [4] => Connection: close
    [5] => Server: Apache
    [6] => Vary: Accept-Encoding
)

在很多情况下,get_headers 已被证明是验证现有 URL 的解决方案

这是一个错误还是 get_headers 不是验证 URL 的可靠方法

See Live Demo

更新 1

发现 CURL 也有同样的问题

$curl = curl_init();
curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => true,CURLOPT_URL => 'idontexist.tld'));
curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
var_dump($info);

Also returns the same result

【问题讨论】:

  • 猜测您是在一个透明代理的后面,该代理正在使用 200 响应代码提供自己的错误页面。可能类似于 OpenDNS。我怀疑您会发现导致此问题的所有域都解析到相同的 IP。
  • @Baba codepad.viper-7.com/s2YnY0 - 注意两个不存在的域如何解析到同一个 IP。就像我说的,您使用的 DNS 服务将不存在的域解析为某个服务器,该服务器为您提供带有 200 响应代码的“友好”错误页面。我承认这是非常烦人的行为,但解决方案是不使用这些服务。如果你想要一个不这样做的通用互联网 DNS 服务,我推荐谷歌的开放服务器 8.8.8.88.8.4.4
  • @SDC 与长度无关,只是名称是否存在。以this 的第一个域为例。
  • 我真的觉得人们应该检查too localized的含义
  • 为什么这个话题被关闭了?这是一个非常有效的问题,根本没有本地化!我现在遇到了同样的问题......

标签: php validation


【解决方案1】:

问题与域名的长度无关,只是域名是否存在。

您正在使用将不存在的域解析为服务器的 DNS 服务,该服务器为您提供“友好”错误页面,并返回 200 响应代码。这意味着 get_headers() 也不是问题,它是任何潜在依赖于合理 DNS 查找的程序。

一种无需为您工作的每个环境硬编码变通的方法来处理此问题的方法可能如下所示:

// A domain that definitely does not exist. The easiest way to guarantee that
// this continues to work is to use an illegal top-level domain (TLD) suffix
$testDomain = 'idontexist.tld';

// If this resolves to an IP, we know that we are behind a service such as this
// We can simply compare the actual domain we test with the result of this
$badIP = gethostbyname($testDomain);

// Then when you want to get_headers()
$url = 'http://www.domainnnnnnnnnnnnnnnnnnnnnnnnnnnn.com/CraxyFile.jpg';

$host = parse_url($url, PHP_URL_HOST);
if (gethostbyname($host) === $badIP) {
  // The domain does not exist - probably handle this as if it were a 404
} else {
  // do the actual get_headers() stuff here
}

您可能希望以某种方式缓存对gethostbyname() 的第一次调用的返回值,因为您知道您正在查找一个不存在的名称,这通常需要几秒钟。

【讨论】:

  • +1 不错...我再问你是这证明get_headers不靠谱
  • @Baba 具体不是get_headers(),它实际上是任何基于名称而不是IP地址在网络上执行任务的函数。但简而言之,不,它不可靠——还有其他原因,因为它依赖于服务器处理 HEAD 请求的方式与处理 GET 请求的方式相同,这在很多方面都不是一个安全的假设(即使它应该符合标准)。
  • 谢谢...我绝对没有发疯
  • get_headers 默认不执行 HEAD 请求,而是执行 GET 请求。 php.net/get_headersbugs.php.net/bug.php?id=55716
猜你喜欢
  • 1970-01-01
  • 2013-09-06
  • 2017-01-16
  • 1970-01-01
  • 2016-02-23
  • 2011-11-10
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
相关资源
最近更新 更多