Appearance
给自己博客加个「IP属地」,访客来自哪一目了然
评论区显示"IP属地:广东",是这几年的流行玩法了。很多博主都想给自己的博客也加上,又怕太麻烦。其实真不难,静态博客都能做。
这篇文章以最常见的两种博客为例,讲讲思路和代码。核心服务用的是 IP9,因为免注册、免key,个人博客用着最省心。
核心思路就三步
- 浏览器访问你的博客,服务器能看到访客的IP;
- 拿这个IP去查归属地(调IP9接口);
- 把"省份城市"返回给前端显示。
关键点:查IP归属地的动作要在服务端做,别在前端直接调第三方接口——前端调的话拿不到真实IP(访问者IP是浏览器和服务器的,前端JS根本不知道),而且会跨域。
如果你是 WordPress / 动态站
直接用PHP查,然后在主题里输出:
php
// functions.php 里加个函数
function get_visitor_location() {
$ip = $_SERVER['REMOTE_ADDR'];
// 走了CDN的话,用这个取真实IP
// $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'];
$resp = wp_remote_get("https://ip9.com.cn/get?ip=$ip", ['timeout' => 3]);
if (is_wp_error($resp)) return '未知';
$data = json_decode(wp_remote_retrieve_body($resp), true);
if ($data['ret'] != 200) return '未知';
return $data['data']['prov'] . ' ' . $data['data']['city'];
}然后在评论区模板里调用:
php
<p class="ip-loc">IP属地:<?php echo get_visitor_location(); ?></p>别忘了加缓存:评论多的话,每个访客都实时查接口不划算。可以在函数里加个Session缓存,或者存成一个临时文件。
如果你是静态博客(Hexo / Hugo / VitePress)
静态博客没有后端,怎么拿IP?两条路:
方案A:评论服务带属地。如果你用的是 Gitalk / Waline / Twikoo 这类有后端的评论系统,直接在评论服务的服务端配置里加IP查询即可,前端零改动。
方案B:Serverless 中转。用云函数(Cloudflare Workers / Vercel Edge)做个代理,由它拿IP查归属地再返回。示例(Cloudflare Worker):
js
export default {
async fetch(request) {
const ip = request.headers.get('CF-Connecting-IP');
const r = await fetch(`https://ip9.com.cn/get?ip=${ip}`);
const data = await r.json();
return new Response(JSON.stringify({
loc: data.ret === 200 ? `${data.data.prov} ${data.data.city}` : '未知'
}), {
headers: { 'content-type': 'application/json', 'access-control-allow-origin': '*' }
});
}
}前端再从这个代理地址拿结果渲染,就搞定了。
显示的时候注意这两点
- 海外用户:没有
prov、city时,就显示国家(country),别让海外访客看到一片空白。 - 容错:查询失败就静默,不显示或者显示"未知",别报错。
为什么我推荐这个方案
这类功能最烦的就是"注册、审核、限次数"。IP9 直接免注册用,接口又是标准GET,静态站、动态站都能接。我自己的博客就是这么挂的,跑了好久一直很稳。
如果你也想给自己博客加上属地,照上面抄就行。接口文档:https://www.ip9.com.cn