如何使用 PHP 获取请求来源?
How I can get origin of request with PHP?
如果有人从 some-client.com
向 some-rest.com
发送 XHR 请求,我想通过 PHP.
可能的解决方案:
- 也许我可以使用
$_SERVER['HTTP_ORIGIN']
但我不知道它是否是一个标准。
- 我看到另一个 header 像
$_SERVER['HTTP_HOST']
或 $_SERVER['SERVER_NAME']
,但有些情况下这个 return 是真实的 hostname
而不是真实的 domain
.
- 并且
$_SERVER['REMOTE_ADDR']
给客户端IP。
使用 PHP 获取请求来源(如域名)的正确方法是什么?
谢谢!
在 php 中,您可以使用 $_SERVER['HTTP_REFERER']。
如果您使用的是 codeigniter,那么您可以使用 $this->agent->is_referral() 获取引荐来源网址。
$_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 headers 不是强制性的,因此标准 Web 浏览器以外的客户端不会设置它。 Next Host header 可能不是强制性的。如果您的 REST 服务器使用虚拟主机,则此 header 是正确路由请求所必需的。但是这个 header 没有关于客户端的任何细节。 http 客户端唯一独特的是 Public IP。但这对应于许多客户端,因为 ISP 使用网络地址转换或代理。
由于一切都是相对的并且在范围内,CORS 类似的机制是建立在 HTTP Origin header 之上的。假定并建议客户使用标准浏览器。
对于你的情况,我认为依赖 Origin header 是可以的。如果适合您,您可以实施 CORS 机制。
根据 MDN 的文章 HTTP access control (CORS):
所有请求必须设置Origin
header才能在CORS(Cross-origin资源共享)机制下正常工作。
“Origin”请求 header 是 RFC 6454 的一部分并且 将其描述为 CORS 机制的一部分 并根据 MDN 与所有浏览器兼容。
MDN 描述:
The Origin
request header indicates where a fetch originates from. It
doesn't include any path information, but only the server name. It is
sent with CORS requests, as well as with POST requests. It is similar
to the Referer header, but, unlike this header, it doesn't disclose
the whole path.
Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
因此,要使用 PHP 获取 XHR 请求的来源,您可以使用:
$_SERVER['HTTP_ORIGIN']
并且,在直接请求的情况下,您可以组合 HTTP_REFERER
和 REMOTE_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 和其他人的帮助。
如果有人从 some-client.com
向 some-rest.com
发送 XHR 请求,我想通过 PHP.
可能的解决方案:
- 也许我可以使用
$_SERVER['HTTP_ORIGIN']
但我不知道它是否是一个标准。 - 我看到另一个 header 像
$_SERVER['HTTP_HOST']
或$_SERVER['SERVER_NAME']
,但有些情况下这个 return 是真实的hostname
而不是真实的domain
. - 并且
$_SERVER['REMOTE_ADDR']
给客户端IP。
使用 PHP 获取请求来源(如域名)的正确方法是什么?
谢谢!
在 php 中,您可以使用 $_SERVER['HTTP_REFERER']。 如果您使用的是 codeigniter,那么您可以使用 $this->agent->is_referral() 获取引荐来源网址。
$_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 headers 不是强制性的,因此标准 Web 浏览器以外的客户端不会设置它。 Next Host header 可能不是强制性的。如果您的 REST 服务器使用虚拟主机,则此 header 是正确路由请求所必需的。但是这个 header 没有关于客户端的任何细节。 http 客户端唯一独特的是 Public IP。但这对应于许多客户端,因为 ISP 使用网络地址转换或代理。
由于一切都是相对的并且在范围内,CORS 类似的机制是建立在 HTTP Origin header 之上的。假定并建议客户使用标准浏览器。
对于你的情况,我认为依赖 Origin header 是可以的。如果适合您,您可以实施 CORS 机制。
根据 MDN 的文章 HTTP access control (CORS):
所有请求必须设置Origin
header才能在CORS(Cross-origin资源共享)机制下正常工作。
“Origin”请求 header 是 RFC 6454 的一部分并且 将其描述为 CORS 机制的一部分 并根据 MDN 与所有浏览器兼容。
MDN 描述:
The
Origin
request header indicates where a fetch originates from. It doesn't include any path information, but only the server name. It is sent with CORS requests, as well as with POST requests. It is similar to the Referer header, but, unlike this header, it doesn't disclose the whole path.Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
因此,要使用 PHP 获取 XHR 请求的来源,您可以使用:
$_SERVER['HTTP_ORIGIN']
并且,在直接请求的情况下,您可以组合 HTTP_REFERER
和 REMOTE_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 和其他人的帮助。