Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

地理位置和服务器 IP 地址问题 #127

Closed
lc6464 opened this issue Feb 7, 2021 · 45 comments
Closed

地理位置和服务器 IP 地址问题 #127

lc6464 opened this issue Feb 7, 2021 · 45 comments
Assignees

Comments

@lc6464
Copy link

lc6464 commented Feb 7, 2021

Is your feature request related to a problem? Please describe.

  1. 服务器 IP 地址仅展示 IPv4 地址,建议增加判断服务器是否支持 IPv6 地址的功能,若支持则同时展示 IPv6 地址,也可以判断用户使用 IPv4 还是 IPv6 访问,并据此选择一个展示。
  2. 获取地理位置功能建议。

Describe the solution you'd like

  1. 获取服务器的 IPv6 地址,并判断其是不是 fe80:: 或者其它类似的开头的本地链路 IPv6 地址,如果存在非本地链路 IPv6 地址,则说明获取到了 IPv6 地址。
  2. 可以参照一下以下代码,不过这个是查文档就能查出来的,我没有查看这个项目的代码,所以只能给出一个几乎没用的建议:
function getPosition(successCallback: PositionCallback, errorCallback: PositionErrorCallback, enableHighAccuracy: boolean) {
	const options = { enableHighAccuracy };
	navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
}

Describe alternatives you've considered

None.

Additional context

None.

@kmvan
Copy link
Owner

kmvan commented Feb 7, 2021

地理信息显示一直想要加上,苦于接口部署。

@lc6464
Copy link
Author

lc6464 commented Feb 7, 2021

使用 CSS 媒体查询来个深色模式怎样?

最好是一开始 CSS 主动决定深色/浅色,允许用户手动更改为系统默认(CSS 媒体查询)/强制深色/强制浅色。

@kmvan
Copy link
Owner

kmvan commented Feb 7, 2021

暗黑模式或定时暗黑模式,都在计划中的。

@kmvan
Copy link
Owner

kmvan commented Feb 9, 2021

思考了一下,如果想要获取服务器公网IPv4和IPv6,那么就必须依靠外部接口来得知。那么这个接口应该如何开发部署,这个需要进一步考究。

@lc6464
Copy link
Author

lc6464 commented Feb 9, 2021

获取 IPv6 地址可以通过检测网卡所拥有的 IP 地址获取,IPv4 就只能靠外部接口了,但是万一有人用反代,很多东西都会出问题。

@kmvan
Copy link
Owner

kmvan commented Feb 9, 2021

获取 IPv6 地址可以通过检测网卡所拥有的 IP 地址获取,IPv4 就只能靠外部接口了,但是万一有人用反代,很多东西都会出问题。

通过网卡获取 IP,这个对 PHP 来说,一般都是没权限的。

@lc6464
Copy link
Author

lc6464 commented Feb 9, 2021

通过网卡获取 IP,这个对 PHP 来说,一般都是没权限的。

也是噢,毕竟 PHP ……
我用 ASP.NET 就没担心过这个,IPv6 和局域网 IPv4 都能直接获取。

@lc6464
Copy link
Author

lc6464 commented Feb 10, 2021

只能用外部接口吧…… ip.sb 有免费的API,也能区分 v6 和 v4 显示

以 PHP 的权限,就只能用外部接口了,或者提供一个附属程序让用户自己搭建,就是要域名。

@kmvan
Copy link
Owner

kmvan commented Feb 10, 2021

可以做一个多ip探测的接口,类似温度传感器功能。但怎么获取来路的ipv4和ipv6, 这个我目前还没思路。

@lc6464
Copy link
Author

lc6464 commented Feb 10, 2021

可以做一个多ip探测的接口,类似温度传感器功能。但怎么获取来路的ipv4和ipv6, 这个我目前还没思路。

获取访问者的 IP 地址的话服务器变量 REMOTE_ADDR 可以用,但是遇到代理/反代照样没救。
X-Forwarded-For 也不一定准确。

@kmvan
Copy link
Owner

kmvan commented Feb 10, 2021

REMOTE_ADDR 只显示单个 IP,而且如果内网网卡优先级高,就直接显示 10.0.0.x,十分尴尬。只能是依靠外部接口才算比较准确

@lc6464
Copy link
Author

lc6464 commented Feb 10, 2021

这个方法确实就是给外部接口用的。
但是只能获取到一个,如果 IPv6 连接的就只能获取到 IPv6,如果启用了临时地址功能的话获取到的还是临时的,
IPv4 连接的话自然就只能获取到 IPv4 了。

@kmvan
Copy link
Owner

kmvan commented Feb 10, 2021

找了一下,最后如果没有其他方法的话,可以用这两个作为备选显示IP4/6:

@lc6464
Copy link
Author

lc6464 commented Feb 10, 2021

我这测试两个都可用,从浏览器开始发起连接到下载完成,两个都约1s.

@lc6464
Copy link
Author

lc6464 commented Feb 10, 2021

第一个大约 110ms,第二个大约300ms.

@kmvan
Copy link
Owner

kmvan commented Feb 10, 2021

使用异步的,快慢不影响页面加载。

@lc6464
Copy link
Author

lc6464 commented Feb 10, 2021

使用异步的,快慢不影响页面加载。

那没事了。
异步也挺好。

@kmvan
Copy link
Owner

kmvan commented Feb 10, 2021

不过实话说这些地址我都不是十分信赖,因为第三方服务没法审查源码,有可能会导致一些不可预料的情况发生。
如果没有其他方法,才把这些地址作为最后一个方案使用。

@lc6464
Copy link
Author

lc6464 commented Feb 10, 2021

不过实话说这些地址我都不是十分信赖,因为第三方服务没法审查源码,有可能会导致一些不可预料的情况发生。
如果没有其他方法,才把这些地址作为最后一个方案使用。

自己部署自然是最好的,但是用户不一定有那么多服务器来部署,而且用户的服务器之间的连接也是个问题。
同一台服务器也不是不可以,就是一定要走公网再绕回来,但是怎么连接还是个问题。
除非全部都让用户自己填写地址什么的,但这样的话有域名的,DDNS 的,才有意义,固定公网 IP 都没啥意义了。

@lc6464
Copy link
Author

lc6464 commented Feb 10, 2021

那确实难说。
不用第三方api也可以自己搭一个,不过维护和稳定性也不容易。

自己搭建 API 的话维护是一个问题,让用户搭的话又有很多不确定因素。

@kmvan
Copy link
Owner

kmvan commented Feb 10, 2021

我用我的服务器搭建 api 就行。

@kmvan
Copy link
Owner

kmvan commented Feb 11, 2021

这两个地址,大家在服务器或本机用 curl 地址或浏览器访问, 能得出对应的 ip 地址吗?
其中 IPv6 这个接口,如果本机dns不支持ipv6,可能就没法访问

@lc6464
Copy link
Author

lc6464 commented Feb 11, 2021

中国移动 100Mbps 网络,响应十分慢,存在一定概率会失败,IPv6 与 IPv4 均是如此。
如果挂了代理,若代理支持 IPv6,则两个响应速度都还可以,若不支持的话 IPv6 显示关闭连接。

代理哪个地区的记不清了。

@kmvan
Copy link
Owner

kmvan commented Feb 12, 2021

了解了

kmvan added a commit that referenced this issue Feb 12, 2021
@kmvan
Copy link
Owner

kmvan commented Feb 12, 2021

试试下载 https://github.com/kmvan/x-prober/tree/dev/dist 探针开发版,增加了服务器ip4/6和地理位置检测显示。

kmvan added a commit that referenced this issue Feb 13, 2021
add dark mode (#127)
@kmvan
Copy link
Owner

kmvan commented Feb 13, 2021

使用 CSS 媒体查询来个深色模式怎样?

最好是一开始 CSS 主动决定深色/浅色,允许用户手动更改为系统默认(CSS 媒体查询)/强制深色/强制浅色。

https://github.com/kmvan/x-prober/tree/dev/dist 探针开发版增加了暗黑模式,可以试试

@lc6464
Copy link
Author

lc6464 commented Feb 17, 2021

v7.1 版本中我的信息中的我的 IPv6 在不支持 IPv6 的网络环境中一直显示加载中。

@kmvan
Copy link
Owner

kmvan commented Feb 17, 2021

v7.1 版本中我的信息中的我的 IPv6 在不支持 IPv6 的网络环境中一直显示加载中。

正常来说超过5秒还是加载中,那大概率是不支持ip6, 因为有些网络即使自身没有ip6, 却不会返回超时或其他状态,只会一直loading,所以我也没办法知道到底它是否支持ip6。只能让它一直loading了。

@lc6464
Copy link
Author

lc6464 commented Feb 17, 2021

正常来说超过5秒还是加载中,那大概率是不支持ip6, 因为有些网络即使自身没有ip6, 却不会返回超时或其他状态,只会一直loading,所以我也没办法知道到底它是否支持ip6。只能让它一直loading了。

那建议每隔一段时间(大约5~10s)重试一次,重试多次(两三次)后还是失败的话就直接显示获取失败了。

第一次获取和后面的重试都先不要取消,等到那次获取/重试发起请求达到30s还是没有响应的话再取消,如果突然某次获取/重试响应了 IPv6 的信息,再把获取失败或者加载中的信息给改掉。
但是千万不要写不支持,显示获取失败,又突然成功还正常点,不支持又突然成功就很诡异。

@kmvan
Copy link
Owner

kmvan commented Feb 17, 2021

确实也是,留意7.2版本更新

@lc6464
Copy link
Author

lc6464 commented Feb 17, 2021

https://prober.inn-studio.com/ 提个建议,加上 favicon.ico.
截图

@kmvan
Copy link
Owner

kmvan commented Feb 17, 2021

还没想到适合这个探针的图案

@lc6464
Copy link
Author

lc6464 commented Feb 18, 2021

截图

在较差的网络状况下(有设备在播放高清视频,且此设备连接的是无线桥接的路由器的 WiFi),IPv4 加载一段时间后显示不支持。

@kmvan
Copy link
Owner

kmvan commented Feb 18, 2021

目前检测ip的方案是,先走 https://ipv4.inn-studio.com/ip?json 如果失败再走 iptest 的那个站点api,若依然失败则走PHP自身的$_SERVER 变量,如果都失败就显示不支持。
从理论上来说,有些网络会只有ip6却没有ip4,有些则反之,所以是没法精确知道到底是不支持ip4还是获取不到ip,因为这些都有空的可能性。

@lc6464
Copy link
Author

lc6464 commented Feb 19, 2021

如果最后获取 REMOTE_ADDR 的话没道理 IPv4 和 v6 都不支持吧?

@kmvan
Copy link
Owner

kmvan commented Feb 19, 2021

如果最后获取 REMOTE_ADDR 的话没道理 IPv4 和 v6 都不支持吧?

主要是 REMOTE_ADDR 这个并不准确,他是当前网卡的ip,可能是内网,可能是回环,也可能是外网。而且 REMOTE_ADDR 这个参数,似乎不分ipv4或6的,基本上没法控制。所以我选择准确度,REMOTE_ADDR 暂时还没办法来判断获取的 ip 是否真实。

@lc6464
Copy link
Author

lc6464 commented Feb 19, 2021

主要是 REMOTE_ADDR 这个并不准确,他是当前网卡的ip,可能是内网,可能是回环,也可能是外网。而且 REMOTE_ADDR 这个参数,似乎不分ipv4或6的,基本上没法控制。所以我选择准确度,REMOTE_ADDR 暂时还没办法来判断获取的 ip 是否真实。

REMOTE_ADDR 理论上来说会是直接访问者的 IP。
如果用了反代的话获取到的就是反代服务器的 IP (如果本机反代的话多半就是 127.0.0.1 或者 ::1)。
特殊设备……确实可能出问题。

@kmvan
Copy link
Owner

kmvan commented Feb 22, 2021

主要是 REMOTE_ADDR 这个并不准确,他是当前网卡的ip,可能是内网,可能是回环,也可能是外网。而且 REMOTE_ADDR 这个参数,似乎不分ipv4或6的,基本上没法控制。所以我选择准确度,REMOTE_ADDR 暂时还没办法来判断获取的 ip 是否真实。

REMOTE_ADDR 理论上来说会是直接访问者的 IP。
如果用了反代的话获取到的就是反代服务器的 IP (如果本机反代的话多半就是 127.0.0.1 或者 ::1)。
特殊设备……确实可能出问题。

试试下载7.2开发版 https://github.com/kmvan/x-prober/tree/dev/dist 测试一下在差网络下的“我的IP”显示状况?

@qingyuan0o0
Copy link

Parse error: syntax error, unexpected '?' in D:\phpStudy\PHPTutorial\WWW\test\x.php on line 2
目前7.2和7.3的版本都碰到这个情况,6.5的版本正常
另外节点应该如何设置呢?

@qingyuan0o0
Copy link

忘记说了,我今天刚好找到一个获取地理位置的,不用重新造轮子
https://github.com/zoujingli/ip2region

@kmvan
Copy link
Owner

kmvan commented Feb 24, 2021

忘记说了,我今天刚好找到一个获取地理位置的,不用重新造轮子
https://github.com/zoujingli/ip2region

这个不错,收藏了

@qingyuan0o0
Copy link

qingyuan0o0 commented Feb 25, 2021

我修改了一段,可以获取自己的,也可以查询
$cxip = isset($_REQUEST['ip'])?($_REQUEST['ip']):"";
$ip2region = new Ip2Region();
function getip(){
$unknown = 'unknown';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown)){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown)) {
$ip = $_SERVER['REMOTE_ADDR'];
}
/**
* 处理多层代理的情况
* 或者使用正则方式:$ip = preg_match("/[\d.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown;
*/
if (false !== strpos($ip, ',')) $ip = reset(explode(',', $ip));
return $ip;
}

$ip=getip();
if (!empty($cxip)) {
$ip= $cxip;
}
$ip2=preg_match("/\d+.\d+.\d+.\d+/",$ip,$ipzz);
//$ip = '61.140.232.170';
//echo PHP_EOL;
echo "{$ipzz[0]}
" . PHP_EOL;

@kmvan
Copy link
Owner

kmvan commented Mar 4, 2021

如果没什么问题就先关闭了,有问题还请继续讨论

@kmvan kmvan closed this as completed Mar 4, 2021
@lc6464
Copy link
Author

lc6464 commented Mar 20, 2021

获取 IPv4、IPv6、地理位置、服务器地理位置 四个功能经常会出现其中一两个加载失败的情况。
估计是网络问题。
令人感到奇怪的是总是其中的一两个加载特别慢甚至失败,剩下的又很快,而且每次快的和慢的还不一样。

@kmvan
Copy link
Owner

kmvan commented Mar 20, 2021

毕竟国际网,正常。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants