前言:你们怎么都开了梯子
最近在开发一个 IP 地址查询工具,核心功能很简单:用户访问网页,显示用户当前的 IP 地址以及推断其所在地(开盒)。
看起来很简单,对吧?后端的 PHP 代码里写一句 $_SERVER['REMOTE_ADDR'] 不就完事了吗?
但在实际测试中,我遇到了一个典型的场景:目标用户群体大多开启了代理软件(如 Clash、v2ray 等)。
如果你开的是“全局模式”,你厉害,我没办法。- 但大部分用户使用的是 “规则模式(分流)”。
难点出现了: 我希望获取到用户本地的真实 IP(如家里的宽带 IP),但我的服务器看到的却是他的 代理IP。
弯路:浏览器的拦路虎 —— CORS 跨域
最初的思路很简单:既然后端获取到的是代理 IP,那就让前端浏览器通过 JS 去请求第三方 IP 接口,拿到结果后再传回后端。
我首先尝试了 fetch('https://ipplus360.com/getIP')。结果控制台直接飘红:
Access to fetch at ‘…’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
原因分析:
这是浏览器同源策略的限制。我所请求的这个第三方接口并没有在其响应头中允许跨域访问。无论我在前端怎么折腾,浏览器都会无情拦截。
破局:核心原理——利用“分流规则”
在分析了多个同类网站的网络请求后,我发现一些老牌 IP 查询网站(如 iplark,ip.skk.moe)竟然能同时显示“本地 IP”和“代理 IP”。但在调试过程中,我发现了一个更有趣的现象,这才是解决问题的核心。
为什么换成国内接口后,就能取到真实 IP 了?
这不仅仅是因为它允许跨域,更是因为代理软件的“分流策略”(Split Routing)。
1. 代理软件的工作逻辑
绝大多数国内用户的代理软件(开启规则模式时)都遵循一套基本逻辑:
- 国外域名
→→匹配规则→→走代理隧道→→暴露代理 IP。 - 国内域名(CN Direct)
→→匹配规则→→直连(Direct)→→暴露本地真实 IP。
2. 顺水推舟的解决方案
既然代理软件会自动区分流量,我们完全可以利用这一点:
- 前端发起请求:JS 强制浏览器请求一个国内的 IP 查询接口(该接口必须支持 CORS)。
- 触发分流规则:用户的代理软件拦截到这个请求,发现目标域名是国内的(如 .cn 后缀)。
- 建立直连:代理软件判定该请求不走代理,直接通过用户的本地网卡/路由器发出。
- 获取真实 IP:目标服务器收到的请求来源是用户的家庭宽带 IP,并将其返回。
- 回传后端:前端拿到这个真实 IP 后,再传给我的后端 PHP 进行地理位置解析。
代码实现
虽然逻辑通了,但在解析 my.ip.cn 返回的数据时,还遇到了页面结构变更的坑。由于该接口返回的是 HTML 而非 JSON,我们需要用正则表达式去提取。
以下是最终的实现代码:
async function getInitialIp() {
try {
// 1. 请求国内接口
// 关键点:该接口支持 CORS,且能触发代理软件的“国内直连”规则
const response = await fetch('https://my.ip.cn/', { cache: 'no-cache' });
if (!response.ok) {
throw new Error('网络响应异常');
}
const text = await response.text();
// 2. 解析 HTML 提取 IP
// 坑点:对方页面结构可能会变(如全角冒号、空格等),正则需要灵活
// 匹配格式示例:"ip:112.10.10.10 归属地:..."
const ipRegex = /ip:(.*?) 归属地/;
const match = text.match(ipRegex);
if (match && match[1]) {
const realIp = match[1].trim();
console.log("利用分流规则成功获取真实IP:", realIp);
// 3. 将真实 IP 传给后端 PHP 进行后续业务处理(如查询经纬度)
fetchGeoData(realIp);
} else {
throw new Error('IP解析失败,页面结构可能已变更');
}
} catch (error) {
console.error("获取IP流程中断:", error);
}
}
最后
首先,要特别感谢 iplark、ip.skk.moe 等IP检测网站,正是研究它们的工作原理,才让我找到了问题的解决方案。
其次,即使你使用了代理,利用“分流规则”依然可能暴露你的真实IP。所以在访问任何网站时,请务必保持对个人网络 IP 安全的警惕。
我没有绕过代理,我只是让代理软件帮我做出了正确的路由选择。
