1 前言
美团通过IP地址可以快速定位,利用美团API可以给网站增加一个定位到访者的插件。
美团API地址为:https://apimobile.meituan.com/locate/v2/ip/loc?rgeo=true&ip=。
本文介绍如何调用美团API定位到访者的IP地址,给自己网站增加一个定位插件。
2 部署教程
2.1 新建ip.php文件
在网站目录下新建ip.php文件,如可以选择在子目录tools下新建ip.php文件,其代码如下:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ip'])) {
$ip = $_POST['ip'];
$ipData = json_decode(file_get_contents("https://apimobile.meituan.com/locate/v2/ip/loc?rgeo=true&ip=" . urlencode($ip)), true);
if (!$ipData || !isset($ipData['data']['lat'])) exit(json_encode(['success' => false]));
$lat = $ipData['data']['lat']; $lng = $ipData['data']['lng']; $rgeo = $ipData['data']['rgeo'];
$cityData = json_decode(file_get_contents("https://apimobile.meituan.com/group/v1/city/latlng/{$lat},{$lng}?tag=0"), true)['data'] ?? [];
exit(json_encode(['success' => true, 'ip' => $ip, 'lat' => $lat, 'lng' => $lng,
'country' => $rgeo['country'] ?? '', 'province' => $rgeo['province'] ?? '',
'city' => $rgeo['city'] ?? '', 'district' => $rgeo['district'] ?? '',
'detail' => $cityData['detail'] ?? '']));
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8"><title>IP Locator</title><meta name="viewport" content="width=device-width,initial-scale=1">
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fastly.jsdelivr.net/npm/[email protected]/dist/leaflet.min.css" rel="stylesheet"/>
<script src="https://fastly.jsdelivr.net/npm/[email protected]/dist/leaflet.min.js"></script>
</head>
<body class="bg-slate-50 font-sans p-3 md:p-6">
<div class="max-w-4xl mx-auto">
<h1 class="text-xl font-medium mb-6 text-center text-gray-700">访客地址</h1>
<div class="grid md:grid-cols-2 gap-4" id="cards"></div>
<div class="text-center text-xs text-gray-400 mt-6">Powered by <a href="https://www.Vvars.com">V+变量建站日记</a></div>
</div>
<script>
(async () => {
const sources = [
{id: 'f', url: 'https://ipv4.lvhai.org/', label: '代理IP', color: '#3b82f6'},
{id: 'd', url: 'https://ipv4_cu.itdog.cn/', label: '访客地址', color: '#10b981'}
];
// Create cards & fetch IPs
sources.forEach(s => {
document.getElementById('cards').innerHTML += `
<div class="bg-white rounded-lg shadow-sm border border-gray-100 overflow-hidden">
<div class="px-3 py-2 border-b border-gray-100 flex items-center justify-between">
<h2 class="text-sm font-medium text-gray-700">${s.label}</h2>
<div class="h-2 w-2 rounded-full" style="background:${s.color}"></div>
</div>
<div id="${s.id}-content" class="p-3 text-sm">
<div class="animate-pulse h-4 w-20 bg-gray-200 rounded"></div>
</div>
<div id="${s.id}-map" class="h-40 rounded-md mt-2 hidden"></div>
</div>`;
// Process IP
(async () => {
try {
// Get IP
const ip = await fetch(s.url).then(r => s.url.includes('lvhai') ?
r.text().then(t => { try { return JSON.parse(t).ip || t.trim(); } catch { return t.trim(); } }) :
r.json().then(j => j.ip)).catch(() => null);
if (!ip) {
document.getElementById(`${s.id}-content`).innerHTML = `<div class="text-red-500">Failed to get IP</div>`;
return;
}
document.getElementById(`${s.id}-content`).innerHTML = `<div class="font-mono text-gray-600">IP: ${ip}</div>`;
// Get location
const data = await fetch(location.href, {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `ip=${encodeURIComponent(ip)}`
}).then(r => r.json());
if (!data.success) {
document.getElementById(`${s.id}-content`).innerHTML += `<div class="text-red-500 text-xs mt-1">Location failed</div>`;
return;
}
// Update content
document.getElementById(`${s.id}-content`).innerHTML = `
<div class="font-mono text-gray-600">IP: ${ip}</div>
<div class="grid grid-cols-2 gap-x-2 gap-y-1 text-xs mt-2">
<div><span class="text-gray-500">国家:</span> ${data.country||'—'}</div>
<div><span class="text-gray-500">省区:</span> ${data.province||'—'}</div>
<div><span class="text-gray-500">城市:</span> ${data.city||'—'}</div>
<div><span class="text-gray-500">区县:</span> ${data.district||'—'}</div>
</div>`;
// Show map with CARTO basemap
const mapEl = document.getElementById(`${s.id}-map`);
mapEl.classList.remove('hidden');
const map = L.map(mapEl, {zoomControl: false, attributionControl: false}).setView([data.lat, data.lng], 10);
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}//{y}{r}.png', {
subdomains: 'abcd'
}).addTo(map);
L.circleMarker([data.lat, data.lng], {radius: 6, color: s.color, weight: 2, fillOpacity: 0.3}).addTo(map);
setTimeout(() => map.invalidateSize(), 100);
} catch (err) {
document.getElementById(`${s.id}-content`).innerHTML = `<div class="text-red-500">Error: ${err.message}</div>`;
}
})();
});
})();
</script>
</body>
</html>
2.2 在网站模板中加入调用代码
可以采用iframe调用,示例代码如下:
<iframe frameborder=0
src="https://www.vvars.com/tools/ip.php"
style="border-radius:8px; height: 300px;
transform: scale(0.85); transform-origin: top left;"></iframe>
代码参考,需要自行调整height和scale数值。
3 最终效果
IP显示:https://www.vvars.com/tools/ip.php
网站调用显示:https://www.vvars.com/Website-construction/Add-a-location-plug-in-to-your-website---call-Meituan-API-to-locate-the-visitor-s-IP-address.html
评论 (0)