Skip to content

HTML 地理定位

HTML Geolocation API 允许 Web 应用程序获取用户设备的地理位置。

隐私警告: 访问位置数据涉及用户隐私。在与网站共享位置之前,浏览器总是会征求用户的许可。

安全提示: 大多数现代浏览器要求网站使用 HTTPS(安全连接)才能访问 Geolocation API。

Geolocation API 得到了所有主要的现代桌面和移动端浏览器的广泛支持。

有关详细的、最新的浏览器兼容性信息,您可以查阅诸如 Can I Use 之类的资源:

位置精度因设备和使用的方法(例如,GPS、Wi-Fi 三角测量、IP 地址查找)而异。带有 GPS 的移动设备通常提供最高的精度。

核心方法是 navigator.geolocation.getCurrentPosition()。它尝试获取设备的当前位置。

此方法至少接受一个参数:一个成功回调函数。如果请求成功,此函数会接收一个包含坐标的 GeolocationPosition 对象。

<!DOCTYPE html>
<html lang="en">
<head>
<title>Geolocation Example</title>
<meta charset="UTF-8">
</head>
<body>
<h1>Geolocation Example</h1>
<button onclick="getLocation()">Try It</button>
<p id="demo"></p>
<script>
const demoElement = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
// 检查浏览器是否支持地理位置功能
demoElement.innerHTML = "Attempting to retrieve location...";
navigator.geolocation.getCurrentPosition(showPosition, showError); // 传递成功和错误处理函数
} else {
demoElement.innerHTML = "Geolocation is not supported by this browser.";
}
}
// 成功回调函数
function showPosition(position) {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
demoElement.innerHTML = `Latitude: ${latitude}<br>Longitude: ${longitude}`;
}
// 错误回调函数(下文解释)
function showError(error) {
// ... (error handling code here)
}
</script>
</body>
</html>

说明:

  • 首先,我们检查 navigator.geolocation 是否存在以确保浏览器支持该功能。
  • 如果支持,我们调用 getCurrentPosition(),将 showPosition 作为成功时运行的函数,将 showError 作为失败时的函数。
  • showPosition 函数接收一个 position 对象。
  • 我们从 position.coords 中提取 latitude 和 longitude 并显示它们。

获取位置可能会因多种原因失败(例如,用户拒绝授权、硬件问题、超时)。getCurrentPosition() 的第二个可选参数是一个错误回调函数。

此函数接收一个包含错误详细信息的 GeolocationPositionError 对象。

// 错误回调函数
function showError(error) {
let errorMessage;
switch(error.code) {
case error.PERMISSION_DENIED:
errorMessage = "User denied the request for Geolocation.";
break;
case error.POSITION_UNAVAILABLE:
errorMessage = "Location information is currently unavailable.";
break;
case error.TIMEOUT:
errorMessage = "The request to get user location timed out.";
break;
case error.UNKNOWN_ERROR:
errorMessage = "An unknown error occurred while trying to get location.";
break;
default:
errorMessage = "An unexpected error occurred.";
}
console.error("Geolocation Error:", error); // 记录错误对象以便调试
demoElement.innerHTML = errorMessage;
}

常见的错误代码:

  • PERMISSION_DENIED:用户在权限提示中点击了“阻止”。
  • POSITION_UNAVAILABLE:确定位置所需的网络或卫星信号不可用。
  • TIMEOUT:浏览器未能在合理的时间内确定位置。
  • UNKNOWN_ERROR:发生了不属于其他类别的未知错误。

始终实现健壮的错误处理机制,以便向用户提供反馈。

一个常见的用例是在交互式地图上显示获取到的坐标。您可以与第三方地图服务集成,例如 Google Maps、OpenStreetMap(通常通过 Leaflet 等库)或 Mapbox。

集成这些服务通常包括:

  • 包含地图库的 JavaScript 文件。
  • 获取 API 密钥(通常需要,尤其是在商业用途中)。
  • 使用库的 API 创建一个以从 Geolocation API 获取的纬度和经度为中心的地图。
  • (可选)在用户位置添加标记。

使用占位符的示例概念(实际实现取决于所选的地图服务):

// 在 showPosition 函数中,获取到纬度/经度后:
// 地图集成的伪代码
// const mapContainer = document.getElementById('map-container');
// mapContainer.style.height = '400px'; // 确保容器有大小
// // 使用假想的 'MappingLibrary' 的示例
// const map = new MappingLibrary.Map(mapContainer, {
// center: [latitude, longitude],
// zoom: 13
// });
//
// new MappingLibrary.Marker({
// position: [latitude, longitude],
// map: map,
// title: '您在此处!'
// });
demoElement.innerHTML =
`Latitude: ${latitude}<br>Longitude: ${longitude}<br><br>` +
`<a href="https://www.openstreetmap.org/?mlat=${latitude}&mlon=${longitude}#map=15/${latitude}/${longitude}" target="_blank">` +
`Show on OpenStreetMap</a>`;

这个更新后的示例提供了一个直接链接到 OpenStreetMap(一个免费的开放地图服务),而不是嵌入复杂的地图库代码。

进一步学习:

watchPosition():

与 getCurrentPosition() 类似,但它会注册一个处理函数,当用户位置显著变化时,此函数会自动被调用。这对于实时跟踪应用(如导航)非常有用。

它返回一个 ID 值,可以与 clearWatch() 一起使用。

clearWatch():

使用 watchPosition 调用返回的 ID,停止正在进行的 watchPosition() 进程。

let watchId = null; // 用于存储监视 ID 的变量
function startWatching() {
if (navigator.geolocation) {
demoElement.innerHTML = "Starting location tracking...";
// 开始监视,存储 ID
watchId = navigator.geolocation.watchPosition(showPosition, showError, { enableHighAccuracy: true });
} else {
demoElement.innerHTML = "Geolocation is not supported.";
}
}
function stopWatching() {
if (watchId !== null) {
navigator.geolocation.clearWatch(watchId); // 停止使用存储的 ID
watchId = null; // 重置 ID
demoElement.innerHTML = "Location tracking stopped.";
} else {
demoElement.innerHTML = "Tracking wasn't active.";
}
}
// showPosition 和 showError 函数与之前相同
// 添加按钮来控制监视:
// <button onclick="startWatching()">开始跟踪</button>
// <button onclick="stopWatching()">停止跟踪</button>

注意:watchPosition 会显著消耗电池电量,尤其是在设置了 enableHighAccuracy: true 时。请谨慎使用,并为用户提供停止跟踪的方式。

成功回调(我们示例中的 showPosition)接收一个 GeolocationPosition 对象。它主要包含:

  • coords:一个包含位置数据的 GeolocationCoordinates 对象。
  • timestamp:指示位置获取时间的 Unix 时间戳。

GeolocationCoordinates 对象包含:

属性描述
latitude纬度,十进制数(必需)。
longitude经度,十进制数(必需)。
accuracy纬度和经度的精度,单位米(必需)。
altitudeWGS84 椭球体上方的高度,单位米(如果不可用则为 null)。
altitudeAccuracy高度的精度,单位米(如果不可用则为 null)。
heading行进方向,单位度(0-360),从正北方向顺时针计算(如果不可用或静止则为 null)。
speed速度,单位米每秒(如果不可用或静止则为 null)。