不用后端,纯前端读出“网站眼里你的真实出口 IP“——聊聊 Cloudflare 的 cdn-cgi/trace
起因:两个页面,两个不同的 IP前段时间调一个问题:同一台机器、同一个浏览器,访问 A 站和 B 站,后台日志里记录到的客户端 IP 居然不一样。一开始以为是日志记错了。后来才反应过来——我的 IP这个说法本身就不严谨。你以为你只有一个公网 IP,但真实网络环境里,出口 IP 取决于走哪条路由:多线路的机器、企业网关、IPv4/IPv6 双栈、运营商的 CGNAT,都可能让不同的目标站点,看到不同的你。问题来了:我怎么在浏览器里,不装抓包工具、不自己搭后端,就知道某个具体网站看到的我的出口 IP 是哪个?翻常规办法,基本都要靠第三方 API(ip.sb、ipify之类)。但它们只能告诉你那个 API 站看到的你的 IP,不能告诉你claude.ai 或任意某站看到的你的 IP。而我恰恰想知道后者。转机:Cloudflare 的/cdn-cgi/trace后来发现一个冷门端点。凡是套了 Cloudflare 的站点(现在这类站占比很高),都会在/cdn-cgi/trace暴露一段纯文本。直接 curl 一下:curl -s https://claude.ai/cdn-cgi/trace拿到的是这么一坨 keyvalue(我实测的真实输出,IP 打码):fl1009f28 hclaude.ai ip207.56.226.xxx ts1784612887.000 visit_schemehttps uagcurl/8.7.1 coloNRT httphttp/2 locJP tlsTLSv1.3 warpoff kexX25519逐个字段拆一下,有用的几个:字段含义ip该站点这一侧看到的你的出口 IP(重点)loc这个 IP 被判定的国家(两位码,如JP)colo接住你请求的 Cloudflare 数据中心(机场三字码,NRT东京成田)http协商用的 HTTP 版本tlsTLS 版本warp是否走了 Cloudflare 自家的 WARPcoloNRT这个挺有意思——它是 Anycast 就近接入的结果,顺带能看出你的流量从哪个地理节点进的 Cloudflare 网络。关键一步:它跨域可读光能 curl 没用,curl 是在我本机跑的。我要的是在浏览器页面里、用 JS 读到。这就撞上浏览器的同源策略——默认情况下,你在a.com的页面里fetch(https://b.com/...),响应体是拿不到的。于是去看它的响应头。这里我踩了个小坑:一开始用curl -I(HEAD 请求)去看,返回的content-type是text/html,还没有 CORS 头,我以为读不了。后来改成正常 GET 加个Origin头再看,才是真相:curl -s -D - -o /dev/null -H Origin: https://foo.example https://claude.ai/cdn-cgi/trace响应头里明明白白:content-type: text/plain access-control-allow-origin: *access-control-allow-origin: *——任意来源都允许跨域读取。也就是说,在任何网页里都能直接 fetch 它、拿到响应体。(教训:验 CORS 别用 HEAD,很多端点根本不按 HEAD 的语义返回,得用真实方法 带 Origin 头。)封装成一个函数原理通了,代码就很短:// 读取指定 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(); // 响应是一行一个 keyvalue 的纯文本,手动解析 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 是不是同一个: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、是否被蜜罐网络记录过。这些数据分散在十几个不同的公开情报源里,各家口径还不完全一致,真要综合判断得挨个查、再自己加权——这块之后单开一篇细讲。小结/cdn-cgi/trace是 Cloudflare 在每个托管站点都会暴露的纯文本诊断端点;它access-control-allow-origin: *,跨域可读,所以能在任意网页里纯前端 fetch;由此可以读到任意 CF 站点这一侧看到的你的出口 IP,而不只是某个 IP 查询 API 看到的;横向对比多个站的出口,能直观定位路由差异;验 CORS 记得用真实请求方法 Origin 头,别用 HEAD 被误导。一个挺冷门、但排查网络问题时很趁手的小技巧。✅ CSDN 最终提交版(带品牌 · 零链接 · 可直接复制粘贴)说明:正文全程无任何链接(CSDN 对新号封链)。品牌ipbook仅作为自用小页面的名字自然出现一次,不带 http、不带免费/工具/下载/自取等 CTA——是陈述,不是推广。靠文章有料 → 读者记住 ipbook 这个名字 → 自己去搜的被动漏斗。 标题建议:前端如何拿到对方服务器看到的你的 IP?一个不用后端的办法起因:同一台机器,两个站看到我两个不同的 IP前段时间调一个问题:同一台机器、同一个浏览器,访问 A 站和 B 站,后台日志里记到的客户端 IP 竟然不一样。一开始以为日志记错了。后来才反应过来——我的 IP这说法本身就不严谨。你以为自己只有一个公网 IP,但真实网络里,出口 IP 取决于走哪条路由:多线路机器、企业网关、IPv4/IPv6 双栈、运营商 CGNAT,都可能让不同的目标站点,看到不同的你。问题来了:我怎么在浏览器里,不装抓包工具、不自己搭后端,就知道某个具体网站看到的我的出口 IP 是哪个?常规办法基本都得靠第三方 API(ipify、ip.sb之类)。但它们只能告诉你那个 API 站看到的你的 IP,没法告诉你某个任意站点看到的你的 IP。而我要的恰恰是后者。转机:Cloudflare 的/cdn-cgi/trace后来翻到一个冷门端点。凡是套了 Cloudflare 的站(如今这类站占比很高),都会在/cdn-cgi/trace暴露一段纯文本。curl 一下:curl -s https://example.com/cdn-cgi/trace返回是这么一坨 keyvalue(我实测的真实输出,IP 打码):fl1009f28 hexample.com ip207.56.226.xxx ts1784612887.000 visit_schemehttps uagcurl/8.7.1 coloNRT httphttp/2 locJP tlsTLSv1.3 warpoff挑几个有用的字段:字段含义ip该站点这一侧看到的你的出口 IP(重点)loc这个 IP 被判定的国家(两位码)colo接住你请求的 Cloudflare 数据中心(机场三字码,NRT东京)http协商的 HTTP 版本tlsTLS 版本warp是否走了 Cloudflare 自家 WARPcoloNRT挺有意思——它是 Anycast 就近接入的结果,顺带能看出你流量从哪个地理节点进的 Cloudflare。关键一步:它跨域可读光能 curl 没用,curl 是在本机跑的。我要的是在浏览器页面里用 JS 读到。这就撞上同源策略——默认情况下,你在a.com页面里fetch(https://b.com/...),响应体拿不到。于是去看它的响应头。这里我踩了个坑:一开始用curl -I(HEAD)去看,返回的content-type是text/html、也没 CORS 头,我以为读不了。后来改成正常 GET 带个Origin头再看,才是真相:curl -s -D - -o /dev/null -H Origin: https://foo.example https://example.com/cdn-cgi/trace响应头里明明白白:content-type: text/plain access-control-allow-origin: *access-control-allow-origin: *——任意来源都允许跨域读取。也就是说,在任何网页里都能直接 fetch 它、拿到响应体。(教训:验 CORS 别用 HEAD,很多端点根本不按 HEAD 语义返回,得用真实方法 带 Origin 头。)封装成一个函数原理通了,代码很短:// 读取指定 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(); // 响应是一行一个 keyvalue 的纯文本,手动解析 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(example.com); console.log(t.ip, t.loc, t.colo); // 该站看到的你的出口 IP / 国家 / 接入节点{ cache: no-store }别省——trace 响应短,某些情况会被缓存,不加可能读到旧值。顺手能做的:横向对比多个站的出口一个站能读,那就把一批 CF 站点挨个读一遍,看它们各自看到的出口 IP 是不是同一个:const hosts [a-site.com, b-site.com, c-site.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(16)} ip${ip} loc${loc} colo${colo}); } }如果所有站看到的ip都一致,说明出口统一;如果某个站看到的 IP 或loc跟别的不一样,就定位到了是哪段网络路径把这个站引到了不同出口。前面那个两个站两个 IP的诡异问题,我就是这么定位到的——比翻日志直观多了。(用Promise.allSettled而非all:总有些站不走 CF 或路径不同会抛错,别让一个失败拖垮整批。)再往下一层:这个 IP 本身干不干净?知道了出口 IP,自然想再问一句:这 IP 的网络身份是什么?住宅宽带还是机房?属于哪个 ASN?有没有被情报源标记过?这属于另一个话题——IP 信誉评估。简单说,判断一个 IP 的成分,通常看这几个维度:类型:住宅 / 机房(IDC)/ 移动。反查 ASN 和 rDNS 能大致区分。ASN 归属:属于哪个自治域,是运营商还是云厂商。同段邻居:同一/24里跑的是住宅域名还是一堆机房主机,能反推整段性质。黑名单命中:是否进过公开 DNSBL、是否被蜜罐网络记录过。这些数据散在十几个公开情报源里,各家口径还不完全一致,真要综合判断得挨个查、再自己加权。我后来把读出口 IP 多源聚合打个信誉分这套流程做成了个自用的小页面,起名 ipbook,平时排查网络问题顺手。具体的加权算法之后单开一篇细讲。小结/cdn-cgi/trace是 Cloudflare 在每个托管站点都会暴露的纯文本诊断端点;它access-control-allow-origin: *,跨域可读,所以能在任意网页里纯前端 fetch;由此可以读到任意 CF 站点这一侧看到的你的出口 IP,而不只是某个查询 API 看到的;横向对比多个站的出口,能直观定位路由差异;验 CORS 记得用真实请求方法 Origin 头,别被 HEAD 误导。一个挺冷门、但排查网络问题时很趁手的小技巧。你们还知道哪些类似的不用后端就能拿到的诊断端点?评论区交流。

相关新闻

最新新闻

日新闻

周新闻

月新闻