PHP $_SERVER['HTTP_HOST'] 与 $_SERVER['SERVER_NAME'],我是否正确理解了手册页?

2022-08-30 06:27:29

我做了很多搜索,还阅读了PHP $_SERVER文档。对于我的 PHP 脚本,对于在整个站点中使用的简单链接定义,我是否具有此权限?

$_SERVER['SERVER_NAME']基于Web服务器的配置文件(在我的情况下是Apache2),并且根据几个指令而变化:(1)VirtualHost,(2)ServerName,(3)UseCanonicalName等。

$_SERVER['HTTP_HOST']基于客户端的请求。

因此,在我看来,为了使我的脚本尽可能兼容而使用的正确方法是 。这个假设是否正确?$_SERVER['HTTP_HOST']

后续评论:

我想在阅读这篇文章后,我有点偏执,并注意到有些人说“他们不会信任任何vars”:$_SERVER

显然,讨论主要是关于以及为什么你不应该在表单操作属性中使用它,而没有适当的转义来防止XSS攻击。$_SERVER['PHP_SELF']

我对上面最初问题的结论是,即使以形式使用,也可以“安全”地用于网站上的所有链接,而不必担心XSS攻击。$_SERVER['HTTP_HOST']

如果我错了,请纠正我。


答案 1

这可能是每个人的第一个想法。但这有点困难。参见Chris Shiflett的文章SERVER_NAME Versus HTTP_HOST

似乎没有银弹。只有当您强制 Apache 使用规范名称时,您才能始终获得带有 的正确服务器名称。SERVER_NAME

因此,您要么这样做,要么根据白名单检查主机名:

$allowed_hosts = array('foo.example.com', 'bar.example.com');
if (!isset($_SERVER['HTTP_HOST']) || !in_array($_SERVER['HTTP_HOST'], $allowed_hosts)) {
    header($_SERVER['SERVER_PROTOCOL'].' 400 Bad Request');
    exit;
}

答案 2

只是一个额外的注意事项 - 如果服务器在80以外的端口上运行(在开发/Intranet计算机上可能很常见),则包含该端口,而不包含该端口。HTTP_HOSTSERVER_NAME

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'

(至少这是我在基于Apache端口的虚拟主机中注意到的)

正如Mike在下面所指出的,在HTTPS上运行时不包含(除非你在非标准端口上运行,我还没有测试过)。HTTP_HOST:443


推荐