从 Chrome 扩展检查观测到的出口 IP
从扩展源向受控端点发起一次受限请求,并说明这次探测究竟能证明什么。
Chrome 扩展中的代理探测需要一个响应可预测的目标。请使用你自行控制的 HTTPS 端点,例如一个返回小型 JSON 对象、其中包含它所观测到的地址的端点。
从扩展上下文(例如其 service worker 或扩展页面)发起请求,并把该端点写入 manifest 的 host permissions:
"host_permissions": ["https://probe.example/*"]
主机权限并不会让 content script 获得同样的跨源特权。请把探测留在扩展上下文中,不要假定注入的脚本能发出同样的请求。
async function probe() {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('https://probe.example/ip', {
cache: 'no-store',
signal: controller.signal,
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
if (typeof result.ip !== 'string') throw new Error('Bad probe body');
return result.ip;
} finally {
clearTimeout(timer);
}
}
主机名只是占位符。服务器与客户端必须就响应格式和缓存策略达成一致。被拒绝的请求和格式异常的响应应在扩展的调用方处理,而不是把它们当作有效的出口地址展示。
准确命名观察结果
成功的结果只能证明这次请求抵达了该端点,并收到了预期形式的响应。在有意义的地方,把观测到的地址与原本计划的路径作比较。 已配置代理的监听 IP 未必就是它的公网出口。
PAC 规则或绕过列表可能让探测直接发出,而另一个目标却走代理。 读取代理设置可以提供配置层面的证据;请求则为此目标提供证据。两者单独都不能证明每个标签页或 URL 都走同一条路径。
在界面中把超时、HTTP 错误和意外响应体区分开。一次请求之后就宣称整台机器离线,不如提示“本次探测失败”有用。