[{"data":1,"prerenderedAt":245},["ShallowReactive",2],{"content:\u002F2026\u002Ftwikoo-ipv4":3,"surround:\u002F2026\u002Ftwikoo-ipv4":239},{"id":4,"title":5,"body":6,"categories":211,"date":213,"description":214,"draft":215,"extension":216,"image":217,"meta":218,"navigation":220,"path":221,"permalink":222,"published":222,"readingTime":223,"recommend":222,"references":222,"seo":228,"sitemap":229,"stem":230,"tags":231,"type":237,"updated":213,"__hash__":238},"content\u002Fposts\u002F2026\u002Ftwikoo-ipv4.md","Twikoo 评论 IP 属地不对，把后端改成 IPv4-only",{"type":7,"value":8,"toc":202},"minimark",[9,13,17,20,31,38,42,45,48,54,57,60,69,72,80,87,94,98,101,104,110,113,116,120,123,126,129,135,138,141,145,152,158,161,167,170,178,181,187,190,193,199],[10,11,12],"h2",{"id":12},"背景",[14,15,16],"p",{},"我的博客是静态页面，托管在 Cloudflare Pages，域名解析也在 Cloudflare。\n评论区用的是 Twikoo，后端单独部署在 Netlify Functions。",[14,18,19],{},"页面和评论是两条路：",[21,22,28],"pre",{"className":23,"code":25,"language":26,"meta":27},[24],"language-txt","blog.zery.cn    -> Cloudflare Pages -> 博客页面\ntwikoo.zery.cn  -> Netlify Function  -> Twikoo 评论后端\n","txt","",[29,30,25],"code",{"__ignoreMap":27},[14,32,33,34,37],{},"后面才发现，这点很重要。因为评论区显示哪个 IP、显示不显示属地，主要看 ",[29,35,36],{"code":36},"twikoo.zery.cn"," 这个后端域名最后把什么 IP 交给了 Twikoo，和博客页面本身是不是走 IPv6、是不是套 CDN 不是一回事。",[10,39,41],{"id":40},"一开始以为是-cdn-的锅","一开始以为是 CDN 的锅",[14,43,44],{},"最早的问题是评论 IP 属地会乱跳，有时是香港，有时是美国。这个现象很迷惑，因为手机没有挂代理，流量显示美国就明显不对了。",[14,46,47],{},"当时链路大概是：",[21,49,52],{"className":50,"code":51,"language":26,"meta":27},[24],"访客\n-> Cloudflare \u002F 其他 CDN\n-> Netlify Function\n-> Twikoo\n",[29,53,51],{"__ignoreMap":27},[14,55,56],{},"这种情况下，Netlify 有可能看到的是 CDN 节点 IP。然后Twikoo 拿节点 IP 去查属地，显示香港、美国就不奇怪了。",[14,58,59],{},"所以第一步先直接查验后端收到的 header。",[21,61,67],{"className":62,"code":64,"filename":65,"language":66,"meta":27},[63],"language-js","const headers = [\n  'cf-connecting-ip',\n  'x-real-ip',\n  'x-forwarded-for',\n  'x-nf-client-connection-ip',\n]\n","debug-ip.js","js",[29,68,64],{"__ignoreMap":27},[14,70,71],{},"手机访问时，看到过类似这样的结果：",[21,73,78],{"className":74,"code":76,"language":77,"meta":27},[75],"language-json","{\n  \"cf-connecting-ip\": \"2409:8938:****:****:****:****:****:****\",\n  \"x-forwarded-for\": \"2409:8938:****:****:****:****:****:****, 162.158.*.*, 50.18.*.*\",\n  \"x-nf-client-connection-ip\": \"162.158.*.*\"\n}\n","json",[29,79,76],{"__ignoreMap":27},[14,81,82,83,86],{},"这里其实已经很清楚了。前面的 ",[29,84,85],{"code":85},"2409:..."," 是手机真实 IPv6，后面的 IPv4 是中间节点。",[14,88,89,90,93],{},"这时如果为了让属地显示出来，取 ",[29,91,92],{"code":92},"x-forwarded-for"," 后面的 IPv4，确实可能有结果，但它只是 CDN 或云平台节点的归属地。",[10,95,97],{"id":96},"关掉小黄云后问题没有结束","关掉小黄云后，问题没有结束",[14,99,100],{},"后来把 Cloudflare 小黄云关了，按理说 CDN 节点这层干扰没了。",[14,102,103],{},"再看 header，变成了这样：",[21,105,108],{"className":106,"code":107,"language":77,"meta":27},[75],"{\n  \"cf-connecting-ip\": \"\",\n  \"x-forwarded-for\": \"2409:8938:****:****:****:****:****:****, 54.254.*.*\",\n  \"x-nf-client-connection-ip\": \"2409:8938:****:****:****:****:****:****\"\n}\n",[29,109,107],{"__ignoreMap":27},[14,111,112],{},"这次 Netlify 拿到的已经是真实客户端 IP，但它是 IPv6。",[14,114,115],{},"问题就从“拿到的是不是本人 IP”，变成了“Twikoo 能不能查这个 IPv6 的属地”。实际表现是：Twikoo 对这个 IPv6 查不出来，于是评论区属地直接空了。",[10,117,119],{"id":118},"别人同样-twikoo-却可以显示","别人同样 Twikoo 却可以显示",[14,121,122],{},"对照了一个同样用 Twikoo 的站。奇了怪了，发现它能显示，但这不代表它一定改了 Twikoo 后端，比如额外加了 IPv6 属地库。",[14,124,125],{},"更可能的区别在 DNS。",[14,127,128],{},"它的评论后端没有 AAAA 记录，只能走 IPv4：",[21,130,133],{"className":131,"code":132,"language":26,"meta":27},[24],"comment.example.com A     x.x.x.x\ncomment.example.com AAAA  none\n",[29,134,132],{"__ignoreMap":27},[14,136,137],{},"手机访问它的评论后端时，最后进后端的就是 IPv4。Twikoo 查 IPv4 没问题，属地自然能出来。",[14,139,140],{},"这也是我最后采用的办法：让评论后端只走 IPv4。",[10,142,144],{"id":143},"域名-dns-怎么改","域名 DNS 怎么改",[14,146,147,148,151],{},"在 Cloudflare DNS 里改 ",[29,149,150],{"code":150},"twikoo"," 这条记录：",[21,153,156],{"className":154,"code":155,"language":26,"meta":27},[24],"Type: A\nName: twikoo\nIPv4 address: 75.2.60.5\nProxy status: DNS only\n",[29,157,155],{"__ignoreMap":27},[14,159,160],{},"然后确认这几件事：",[21,162,165],{"className":163,"code":164,"language":26,"meta":27},[24],"没有 AAAA\n没有 CNAME\n小黄云关闭\n",[29,166,164],{"__ignoreMap":27},[14,168,169],{},"可以用 DNS-over-HTTPS 查一下，避免本地代理或者 Fake-IP 影响判断：",[21,171,176],{"className":172,"code":174,"language":175,"meta":27},[173],"language-powershell","Invoke-RestMethod `\n  -Uri \"https:\u002F\u002Fcloudflare-dns.com\u002Fdns-query?name=twikoo.zery.cn&type=A\" `\n  -Headers @{ accept = 'application\u002Fdns-json' }\n\nInvoke-RestMethod `\n  -Uri \"https:\u002F\u002Fcloudflare-dns.com\u002Fdns-query?name=twikoo.zery.cn&type=AAAA\" `\n  -Headers @{ accept = 'application\u002Fdns-json' }\n","powershell",[29,177,174],{"__ignoreMap":27},[14,179,180],{},"这边最终期望是：",[21,182,185],{"className":183,"code":184,"language":26,"meta":27},[24],"A     75.2.60.5\nAAAA  none\n",[29,186,184],{"__ignoreMap":27},[14,188,189],{},"DNS 生效后，再用手机流量发一条新评论。",[14,191,192],{},"新的 header 应该接近这样：",[21,194,197],{"className":195,"code":196,"language":77,"meta":27},[75],"{\n  \"x-forwarded-for\": \"183.217.*.*, 3.1.*.*\",\n  \"x-nf-client-connection-ip\": \"183.217.*.*\"\n}\n",[29,198,196],{"__ignoreMap":27},[14,200,201],{},"这时 Twikoo 拿到的是 IPv4，归属地就能正常显示。",{"title":27,"searchDepth":203,"depth":203,"links":204},4,[205,207,208,209,210],{"id":12,"depth":206,"text":12},2,{"id":40,"depth":206,"text":41},{"id":96,"depth":206,"text":97},{"id":118,"depth":206,"text":119},{"id":143,"depth":206,"text":144},[212],"部署运维","2026-05-12 14:35:00","记录一次 Twikoo + Netlify 评论后端的 IP 属地显示错误排查。",false,"md","https:\u002F\u002Fimg.zery.cn\u002F202605\u002Ftwikoo-ipv4.webp",{"slots":219},{},true,"\u002F2026\u002Ftwikoo-ipv4",null,{"text":224,"minutes":225,"time":226,"words":227},"4 min read",3.85,231000,770,{"title":5,"description":214},{"loc":221},"posts\u002F2026\u002Ftwikoo-ipv4",[232,233,234,235,236],"Twikoo","Netlify","Cloudflare","IPv6","DNS","tech","G8S1RX6oecyGXly1r6I7N6a7G4TWCffueHqIuKpZlP8",[240,222],{"title":241,"path":242,"stem":243,"date":244,"type":237,"children":-1},"Hello, Zery Notes","\u002F2026\u002Fhello-world","posts\u002F2026\u002Fhello-world","2026-05-10 14:12:58",1778586771594]