如何使用 PHP 获取请求的来源?

Posted

技术标签:

【中文标题】如何使用 PHP 获取请求的来源?【英文标题】:How I can get origin of request with PHP? 【发布时间】:2017-05-10 14:58:39 【问题描述】:

如果有人从some-client.comsome-rest.com 发送 XHR 请求,我想用 php 获取请求的来源(域名,而不是客户端 ip)。

可能的解决方案:

也许我可以使用$_SERVER['HTTP_ORIGIN'],但我不知道它是否是标准。 我看到另一个标题,例如 $_SERVER['HTTP_HOST']$_SERVER['SERVER_NAME'],但在某些情况下,这会返回真正的 hostname,而不是真正的 domain$_SERVER['REMOTE_ADDR'] 提供客户端 IP。

使用 PHP 获取请求来源(如域名)的正确方法是什么?

谢谢!

【问题讨论】:

据我所知,$_SERVER['REMOTE_ADDR'] 是您的解决方案,您只能获取 IP 而不能获取 DNS 【参考方案1】:

根据MDN的文章HTTP access control (CORS)

所有请求都必须设置Origin标头才能在CORS(跨域资源共享)机制下正常工作。

Origin”请求标头是 RFC 6454 的一部分,将其描述为 CORS 机制的一部分,并且根据 MDN 与所有浏览器兼容。

MDN 的描述:

Origin 请求标头指示提取的来源。它 不包含任何路径信息,而仅包含服务器名称。它是 与 CORS 请求以及 POST 请求一起发送。这是相似的 到 Referer 标头,但与此标头不同的是,它不透露 整个路径。

来源:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin

MDN 示例:

因此,要使用 PHP 获取 XHR 请求的来源,您可以使用:

$_SERVER['HTTP_ORIGIN'] 

而且,如果是直接请求,您可以结合 HTTP_REFERERREMOTE_ADDR 像:

if (array_key_exists('HTTP_REFERER', $_SERVER)) 
    $origin = $_SERVER['HTTP_REFERER'];
 else 
    $origin = $_SERVER['REMOTE_ADDR'];

因此,可能的最终解决方案是:

if (array_key_exists('HTTP_ORIGIN', $_SERVER)) 
    $origin = $_SERVER['HTTP_ORIGIN'];

else if (array_key_exists('HTTP_REFERER', $_SERVER)) 
    $origin = $_SERVER['HTTP_REFERER'];
 else 
    $origin = $_SERVER['REMOTE_ADDR'];

MDN 是Mozilla Developer Network。

非常感谢@trine、@waseem-bashir、@p0lt10n 和其他人的帮助。

【讨论】:

【参考方案2】:

在 php 中你可以使用 $_SERVER['HTTP_REFERER']。 如果您使用的是 codeigniter,那么您可以使用 $this->agent->is_referral() 获取引用者。

【讨论】:

这是 `Referer` 标头,某些浏览器不使用此标头。在此处了解更多信息:en.wikipedia.org/wiki/HTTP_referer【参考方案3】:
$_SERVER['HTTP_ORIGIN']  // HTTP Origin header
$_SERVER['HTTP_HOST']    // HTTP Host header
$_SERVER['HTTP_REFERER'] // HTTP Referer header
$_SERVER['REMOTE_ADDR']  // HTTP Client's Public IP

让我们在上面讨论$_SERVER参数。

首先,XHR 在客户端,它与 http 客户端绑定。由于 Origin 和 Referer 标头不是强制性的,因此标准 Web 浏览器以外的客户端不会设置该标头。 Next Host 标头可能不是强制性的。如果您的 REST 服务器使用虚拟主机,则此标头是正确路由请求所必需的。但是此标头没有有关客户端的任何详细信息。 http 客户端唯一的独特之处是公共 IP。但这对应于许多客户端,因为 ISP 使用网络地址转换或代理。

由于一切都是相对的并且在范围内,CORS 之类的机制是建立在 HTTP Origin 标头上的。假定并建议客户使用标准浏览器。

在您的情况下,我认为可以依赖 Origin 标头。如果适合你,你可以实现CORS机制。

【讨论】:

以上是关于如何使用 PHP 获取请求的来源?的主要内容,如果未能解决你的问题,请参考以下文章

PHP如何判断一个请求是不是来源于本域并且是ajax请求?

图解 nginx 如何获取真实的来源 IP

PHP:如何获取引荐来源网址?

php模拟post请求,获取不到数据

如何使用 SQL 和 PHP 从数据库 (phpMyAdmin) 的字段中获取/请求所有值?

ASP.NET中如何获得最初请求来源