设想
我在服务器上有一个小型 PHP 脚本,它会回显任何到达它的客户端的 IP 地址,以便可以通过 API 将地址添加到 cpanel MySQL 远程主机表中。我使用 IdHTTP1.Get() 传递脚本的 url 来调用此脚本。我正在通过使用 Bitdefender VPN 来测试这一点,每次运行 delphi 代码获取当前 IP 地址之前都会给我一个新的 IP 地址。PHP脚本的代码和delphi调用代码如下。
问题
如果我打开 VPN 给自己一个新的 IP 地址,然后运行代码,它会返回一个 IPv6 地址。如果我再次运行代码,而不断开 VPN,即我仍然具有相同的地址,那么在第二次调用时我会获得 IPv4 地址。随后每次运行代码时,我都会得到相同的 IPv4 地址,正如我所期望的那样。
如果我关闭 VPN 并再次打开它以获取不同的 IP 地址,则会发生同样的情况。即,我第一次运行代码时获得 IPv6 地址,随后获得 IPv4 地址
例如 第一次:2a02:2498:e000:2001:8418:7195:9f43:a0f 第二次及后续时间:88.202.181.53
这篇文章解释了两种地址格式都可能会被返回,但我得到的模式似乎非常一致。
问题
有没有办法强制代码始终返回 IPv4 地址?(我的代码无需反复询问地址,直到获得 IPv4 中的地址)
附加信息
这篇文章似乎暗示了一个解决方案,但我并没有真正理解所接受的答案足以将其应用到我的案例中。
此页面https://www.ipify.org/在 API 使用下,展示了如何使用https://api.ipify.org或https://api64.ipify.org获取我的 IPv4 或 IPv6 地址,因此应该是可以在我的脚本中说出我想要的内容
myip.php 代码
<?php
$ip=$_SERVER['REMOTE_ADDR'];
echo $ip;
?>
调用PHP脚本的Delphi函数(IdHTTP1是表单上的Indy TIdHTTP组件)
function TFrmMain.getmyipaddress: string;
var url : string;
begin
url := 'https://Thedomain.com/myip.php';
Result := '';
try
try
theip := IdHTTP1.Get(url);
Result := Trim(theip);
if result = '' then showmessage( 'Failed to get a sensible IP address from myip.php on server:');
finally
end;
except
on E: Exception do
ShowMessage('Failed to get IP address from myip.php on server:' +slinebreak +
e.Message);
end;
end;
ipify.org 只能告诉您 IPv4 和 IPv6 地址,因为它具有不同的 IPv6 和 IPv4 域。https://www.ipify.org/网站将使用 JavaScript 向不同的域发出请求。
可以使用 IPv4 或 IPv6 发出 http 请求,网络服务器自然会从 TCP 标头中知道您的连接 IP 地址 - 毕竟,这是它发送响应的地方。由客户端决定是通过 IPv4 还是 IPv6 发出 http 请求,但如果域只有 A (IPv4) 或 AAAA (IPv6) 记录,则客户端实际上别无选择。
域名 api6.ipify.org 仅解析为 IPv6 地址,api4.ipify.org 仅解析为 IPv4,因此客户端永远无法通过 IPv6 连接到 api4.ipify.org,反之亦然。
如果您希望 php 脚本始终返回客户端的 IPv4 地址,请确保无法通过将其托管在只能解析为 IPv4 地址的域上来通过 IPv6 连接。
PHP
$_SERVER['REMOTE_ADDR']
包含为发出请求而打开的套接字的远程地址。它可以是 IPv4 或 IPv6 地址,具体取决于客户端选择使用的地址。客户端在连接到域时选择 IPv4 或 IPv6 有几个标准:
因此,如果要确保
REMOTE_ADDR
始终具有 IPv4 地址,则需要使用仅具有 A 记录的域名。如果您可以控制客户端的网络,则可以在客户端中禁用 IPv6。