
通过前端获取地理位置并结合后端存储,实现“上次访问来自xx城市,xx国家”的动态提示功能。需借助ip定位服务、服务器端持久化及前端展示逻辑。
要在网页右下角(或其他位置)显示类似 “Last visit from Tokyo, Japan” 的提示,仅靠纯前端 javaScript(如 navigator.geolocation.getCurrentPosition())是无法实现的——因为该 API 仅能获取当前会话的精确地理位置,且需用户授权、不适用于无 GPS 的桌面环境,更无法追溯“上次访问”信息。
真正的解决方案依赖前后端协同:
✅ 核心逻辑流程
- 每次用户访问页面时,前端向你的后端发起请求(如 /api/track-visit);
- 后端通过请求的 IP 地址调用第三方 IP 归属地服务(如 ipapi.co、ipgeolocation.io 或 MaxMind GeoLite2),解析出 city 和 country_name;
- 后端将该地理位置信息连同时间戳存入数据库(如 redis 快速缓存或 postgresql 持久表),并更新为该用户的“最新访问记录”;
- 前端在页面加载时,再发起一次轻量请求(如 /api/last-visit)获取已存储的上一次有效位置,并渲染到 dom 中。
? 示例:简易后端(node.js + express)
// server.js(需安装 axios) app.get('/api/last-visit', (req, res) => { // 假设使用 Redis 存储:key = 'last_visit:123.45.67.89' const ip = req.ip || req.connection.remoteAddress; redis.get(`last_visit:${ip}`, (err, data) => { if (data) { res.json(JSON.parse(data)); // { city: "Berlin", country: "Germany", timestamp: "2024-05-20T14:22:00Z" } } else { res.json({ city: "Unknown", country: "Unknown" }); } }); }); app.get('/api/track-visit', async (req, res) => { const ip = req.ip || req.connection.remoteAddress; try { const geoRes = await axios.get(`https://www.php.cn/link/8e9368bb8083221506d9b1c83c5c7d95${ip}/json/`, { headers: { 'User-Agent': 'YourSite/1.0' } }); const { city, country_name } = geoRes.data; const record = { city, country: country_name, timestamp: new Date().toISOString() }; redis.setex(`last_visit:${ip}`, 60 * 60 * 24 * 7, json.stringify(record)); // 缓存7天 res.json(record); } catch (e) { res.json({ city: "Unknown", country: "Unknown" }); } });
?️ 前端展示(html + JS)
Last visit from —, —
// 在页面加载完成后执行 async function loadLastVisit() { try { const res = await fetch('/api/last-visit'); const data = await res.json(); document.getElementById('lv-city').textContent = data.city || '—'; document.getElementById('lv-country').textContent = data.country || '—'; } catch (e) { console.warn('Failed to load last visit info', e); } } loadLastVisit(); // 可选:每次页面可见时刷新追踪(提升准确性) document.addEventListener('visibilitychange', () => { if (!document.hidden) fetch('/api/track-visit').catch(() => {}); });
⚠️ 注意事项
- 隐私合规:根据 GDPR / CCPA,需在使用 IP 定位前明确告知用户并获得同意(可在 cookie Banner 中说明);
- IP 精度限制:IP 定位通常精确到城市级,无法替代 GPS,且企业网络、代理、CDN 可能返回网关位置;
- 免费额度:如使用 ipapi.co 免费版(1000 次/日),注意请求频控;生产环境建议搭配缓存(Redis)降低调用次数;
- 不要依赖 navigator.geolocation 实现“上次访问”:它只提供本次实时位置,且拒绝率高、移动端体验差。
通过这一架构,你就能像 rauno.me 那样,在页面角落优雅呈现带有地理语义的访问记忆——既专业,又尊重用户数据边界。