不用后端,纯前端读出"网站眼里你的真实出口 IP"——聊聊 Cloudflare 的 cdn-cgi/trace

起因:两个页面,两个不同的 IP

前段时间调一个问题:同一台机器、同一个浏览器,访问 A 站和 B 站,后台日志里记录到的客户端 IP 居然不一样。

一开始以为是日志记错了。后来才反应过来------ "我的 IP"这个说法本身就不严谨。你以为你只有一个公网 IP,但真实网络环境里,出口 IP 取决于走哪条路由:多线路的机器、企业网关、IPv4/IPv6 双栈、运营商的 CGNAT,都可能让"不同的目标站点,看到不同的你"。

问题来了:我怎么在浏览器里,不装抓包工具、不自己搭后端,就知道"某个具体网站看到的我的出口 IP 是哪个"?

翻常规办法,基本都要靠第三方 API(ip.sbipify 之类)。但它们只能告诉你"那个 API 站 看到的你的 IP",不能告诉你"claude.ai 或任意某站看到的你的 IP"。而我恰恰想知道后者。

转机:Cloudflare 的 /cdn-cgi/trace

后来发现一个冷门端点。凡是套了 Cloudflare 的站点(现在这类站占比很高),都会在 /cdn-cgi/trace 暴露一段纯文本。直接 curl 一下:

arduino 复制代码
curl -s https://claude.ai/cdn-cgi/trace

拿到的是这么一坨 key=value(我实测的真实输出,IP 打码):

ini 复制代码
fl=1009f28
h=claude.ai
ip=207.56.226.xxx
ts=1784612887.000
visit_scheme=https
uag=curl/8.7.1
colo=NRT
http=http/2
loc=JP
tls=TLSv1.3
warp=off
kex=X25519

逐个字段拆一下,有用的几个:

字段 含义
ip 该站点这一侧看到的你的出口 IP(重点)
loc 这个 IP 被判定的国家(两位码,如 JP)
colo 接住你请求的 Cloudflare 数据中心(机场三字码,NRT=东京成田)
http 协商用的 HTTP 版本
tls TLS 版本
warp 是否走了 Cloudflare 自家的 WARP

colo=NRT 这个挺有意思------它是 Anycast 就近接入的结果,顺带能看出你的流量从哪个地理节点进的 Cloudflare 网络。

关键一步:它跨域可读

光能 curl 没用,curl 是在我本机跑的。我要的是在浏览器页面里、用 JS 读到 。这就撞上浏览器的同源策略------默认情况下,你在 a.com 的页面里 fetch('https://b.com/...'),响应体是拿不到的。

于是去看它的响应头。这里我踩了个小坑:一开始用 curl -I(HEAD 请求)去看,返回的 content-typetext/html,还没有 CORS 头,我以为读不了。后来改成正常 GET + 加个 Origin 头再看,才是真相:

bash 复制代码
curl -s -D - -o /dev/null -H "Origin: https://foo.example" https://claude.ai/cdn-cgi/trace

响应头里明明白白:

less 复制代码
content-type: text/plain
access-control-allow-origin: *

access-control-allow-origin: * ------任意来源都允许跨域读取。也就是说,在任何网页里都能直接 fetch 它、拿到响应体。(教训:验 CORS 别用 HEAD,很多端点根本不按 HEAD 的语义返回,得用真实方法 + 带 Origin 头。)

封装成一个函数

原理通了,代码就很短:

javascript 复制代码
// 读取"指定 CF 站点这一侧,看到的你的出口 IP 及网络信息"
// 纯前端,无需任何后端或第三方 API
async function readTrace(host) {
  const res = await fetch(`https://${host}/cdn-cgi/trace`, { cache: 'no-store' });
  if (!res.ok) throw new Error(`${host} 未返回 trace(可能没走 Cloudflare)`);
  const text = await res.text();


  // 响应是一行一个 key=value 的纯文本,手动解析
  return Object.fromEntries(
    text.trim().split('\n').map((line) => {
      const i = line.indexOf('=');
      return [line.slice(0, i), line.slice(i + 1)];
    })
  );
}


// 用法
const t = await readTrace('claude.ai');
console.log(t.ip, t.loc, t.colo);  // 该站看到的你的出口 IP / 国家 / 接入节点

{ cache: 'no-store' } 别省------trace 端点响应短,某些情况下会被缓存,不加可能读到旧值。

顺手能做的一件事:横向对比多个站的出口

一个站能读,那就把一批 CF 站点挨个读一遍,看看它们各自看到的出口 IP 是不是同一个:

ini 复制代码
const hosts = ['claude.ai', 'openai.com', 'www.cloudflare.com', 'anthropic.com'];


const results = await Promise.allSettled(
  hosts.map(async (h) => ({ host: h, ...(await readTrace(h)) }))
);


for (const r of results) {
  if (r.status === 'fulfilled') {
    const { host, ip, loc, colo } = r.value;
    console.log(`${host.padEnd(22)} ip=${ip}  loc=${loc}  colo=${colo}`);
  }
}

如果所有站看到的 ip 都一致,说明你的出口是统一的;如果某个站看到的 IP 或 loc 跟别的不一样,那就定位到了"是哪一段网络路径把这个站的流量引到了不同出口"。前面那个"两个页面两个 IP"的诡异问题,我就是这么定位到的------比翻日志直观多了

(用 Promise.allSettled 而不是 all:总有些站不走 CF,或路径不同会抛错,别让一个失败拖垮整批。)

再往下一层:这个 IP 本身"干不干净"?

知道了出口 IP,自然会想再问一句:这个 IP 的"网络身份"是什么?是住宅宽带、还是机房 IP?属于哪个 ASN?有没有被各类情报源标记过?

这属于另一个话题了------IP 信誉评估。简单说,判断一个 IP 的"成分",通常看这几个维度:

  • 类型:住宅 / 机房(IDC)/ 移动。反查 ASN 和 rDNS 能大致区分。
  • ASN 归属:这个 IP 属于哪个自治域,是电信运营商还是云厂商。
  • 同段邻居 :同一 /24 网段里跑的是住宅域名还是一堆机房主机,能反推整段性质。
  • 黑名单命中:是否进过公开的 DNSBL、是否被蜜罐网络记录过。

这些数据分散在十几个不同的免费情报源里,单独查很累。我后来把"读出口 IP + 多源聚合打个信誉分"这套流程整个做成了个页面,平时排查网络问题顺手用。

小结

  • /cdn-cgi/trace 是 Cloudflare 在每个托管站点都会暴露的纯文本诊断端点;
  • access-control-allow-origin: *,跨域可读,所以能在任意网页里纯前端 fetch;
  • 由此可以读到"任意 CF 站点这一侧看到的你的出口 IP",而不只是某个 IP 查询 API 看到的;
  • 横向对比多个站的出口,能直观定位路由差异;
  • 验 CORS 记得用真实请求方法 + Origin 头,别用 HEAD 被误导。

一个挺冷门、但排查网络问题时很趁手的小技巧。

相关推荐
程序员黑豆6 小时前
鸿蒙开发入门:Row 和 Column 布局组件详解
前端·harmonyos
hoLzwEge7 小时前
前端环境变量配置指南:.env 文件详解
前端·前端框架
hunterandroid7 小时前
Paging 3 RemoteMediator 实战:构建离线优先的分页列表
android·前端
Underwood_177 小时前
星级评价——了解useState
前端
hunterandroid7 小时前
[鸿蒙从零到一] ArkUI 组件化实战:构建可复用、可组合的自定义组件
前端·华为·架构
一只公羊7 小时前
iPhone摄像头 在开发/调试过程中强行停止 App,导致 `AVCaptureSession` 没有被正常释放
前端
浮江雾8 小时前
Flutter第十节-----Flutter布局与组件全解析
android·开发语言·前端·学习·flutter·入门
xcLeigh8 小时前
Doubao-Seed-Evolving大模型接入教程|搭建全品类提示词+AI工具导航网页
前端·人工智能·python·ai·html·ai开发·豆包