跳转到内容

Geolocation API:获取用户位置

一句话: 在浏览器获得明确权限后,navigator.geolocation 提供用户的物理位置(纬度、 经度,以及可选的海拔/精度)——访问始终由用户发起,并受权限提示约束,页面无法绕过。

navigator.geolocation.getCurrentPosition(
(position) => {
const { latitude, longitude, accuracy } = position.coords;
console.log(`${latitude}, ${longitude}${accuracy}m)`);
},
(error) => {
// error.code:1=PERMISSION_DENIED, 2=POSITION_UNAVAILABLE, 3=TIMEOUT
console.error(`定位错误 ${error.code}${error.message}`);
},
{
enableHighAccuracy: false, // GPS vs 网络定位;电量权衡
timeout: 10_000, // 超过此时间触发错误回调(ms)
maximumAge: 60_000, // 接受最多 60 秒前的缓存位置
}
);

watchPosition 返回监听 ID,每当位置变化时触发成功回调。不再需要跟踪时调用 clearWatch(id)

const watchId = navigator.geolocation.watchPosition(
(pos) => updateMap(pos.coords),
(err) => handleError(err)
);
// 不再需要跟踪时:
navigator.geolocation.clearWatch(watchId);

定位访问始终受浏览器显式权限提示约束。首次调用 getCurrentPositionwatchPosition 时,浏览器会询问用户“是否允许 [网站] 获取您的位置?”。规范要求此提示 不能被抑制、预先回答,或在没有浏览上下文时触发。

  • 用户可以选择允许拒绝或(某些浏览器)仅允许本次
  • 被拒绝的授权会通过 error.code === 1PERMISSION_DENIED)反映在错误回调中。 代码必须优雅处理此情况——显示手动位置输入的回退,或给出上下文说明。
  • 可通过 Permissions API 在不触发提示的情况下查询当前权限状态: navigator.permissions.query({ name: 'geolocation' }) 解析为 { state: 'granted' | 'denied' | 'prompt' }

Geolocation 仅在安全上下文中可用——HTTPS 或 localhost。在普通 HTTP 下,无论什么 浏览器,navigator.geolocation 均为 undefined

无需用户手势(但仍会显示提示)

Section titled “无需用户手势(但仍会显示提示)”

与某些 API 不同,调用 getCurrentPosition 不需要活跃的用户手势。然而,浏览器仍会显示 权限提示,未预期到的用户通常会拒绝。为获得最高授权率,请仅在用户明确请求基于位置的功能 时(如点击“使用我的位置”按钮)才调用定位。

设置 enableHighAccuracy: true 请求 GPS 质量的位置。这会更快消耗电量,且冷启动耗时 更长。仅在确实需要 50 米以内精度时(逐向导航)才设置此项。对于“附近”查询,默认的 (false)网络定位通常已足够精确。

  • 不要在完成所需任务后继续存储原始坐标。
  • 在触发提示前清晰披露位置用途——用户了解原因后授权率更高。
  • 除非精度至关重要,否则优先使用粗略位置(enableHighAccuracy: false)。

当前各浏览器数据请参见 /compatibility/

决策问题 建议行为 理由
一次性位置查询? 使用 getCurrentPosition,设合理的 timeoutmaximumAge 避免持续跟踪消耗;maximumAge 可立即返回最近缓存的定位。
实时位置跟踪(地图、导航)? 使用 watchPosition,完成后 clearWatch 保持定位更新;功能不活跃时始终停止监听。
需要在不触发提示的情况下检查权限状态? navigator.permissions.query({ name: 'geolocation' }) 允许条件性 UI,而不触发意外提示。
用户拒绝了——怎么办? 显示手动地址/城市输入;解释位置的用途。 PERMISSION_DENIED 在用户手动在浏览器设置中重置之前是永久的。
精度与电量权衡? 默认 enableHighAccuracy: false;仅导航时设为 true 对“附近”功能而言,GPS 精度很少值得电量代价。
  • 通过 HTTPS 提供页面——普通 HTTP 下 Geolocation 不可用。
  • 仅在用户明确选择使用位置功能时才调用 getCurrentPosition/watchPosition
  • 处理所有三种错误码:PERMISSION_DENIED(1)、POSITION_UNAVAILABLE(2)、TIMEOUT(3)。
  • 为拒绝或不可用情况提供非位置回退(如手动地址输入)。
  • 每次调用都设置 timeout 和合理的 maximumAge
  • 不再需要持续跟踪时始终调用 clearWatch(),避免电量消耗。
  • 如需有条件显示或隐藏位置功能,先用 Permissions API 查询权限状态。