Geolocation API:获取用户位置
一句话: 在浏览器获得明确权限后,navigator.geolocation 提供用户的物理位置(纬度、
经度,以及可选的海拔/精度)——访问始终由用户发起,并受权限提示约束,页面无法绕过。
单次:getCurrentPosition
Section titled “单次:getCurrentPosition”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
Section titled “持续跟踪:watchPosition”watchPosition 返回监听 ID,每当位置变化时触发成功回调。不再需要跟踪时调用
clearWatch(id):
const watchId = navigator.geolocation.watchPosition( (pos) => updateMap(pos.coords), (err) => handleError(err));
// 不再需要跟踪时:navigator.geolocation.clearWatch(watchId);定位访问始终受浏览器显式权限提示约束。首次调用 getCurrentPosition 或
watchPosition 时,浏览器会询问用户“是否允许 [网站] 获取您的位置?”。规范要求此提示
不能被抑制、预先回答,或在没有浏览上下文时触发。
- 用户可以选择允许、拒绝或(某些浏览器)仅允许本次。
- 被拒绝的授权会通过
error.code === 1(PERMISSION_DENIED)反映在错误回调中。 代码必须优雅处理此情况——显示手动位置输入的回退,或给出上下文说明。 - 可通过 Permissions API 在不触发提示的情况下查询当前权限状态:
navigator.permissions.query({ name: 'geolocation' })解析为{ state: 'granted' | 'denied' | 'prompt' }。
安全上下文(HTTPS)
Section titled “安全上下文(HTTPS)”Geolocation 仅在安全上下文中可用——HTTPS 或 localhost。在普通 HTTP 下,无论什么
浏览器,navigator.geolocation 均为 undefined。
无需用户手势(但仍会显示提示)
Section titled “无需用户手势(但仍会显示提示)”与某些 API 不同,调用 getCurrentPosition 不需要活跃的用户手势。然而,浏览器仍会显示
权限提示,未预期到的用户通常会拒绝。为获得最高授权率,请仅在用户明确请求基于位置的功能
时(如点击“使用我的位置”按钮)才调用定位。
enableHighAccuracy 与电量
Section titled “enableHighAccuracy 与电量”设置 enableHighAccuracy: true 请求 GPS 质量的位置。这会更快消耗电量,且冷启动耗时
更长。仅在确实需要 50 米以内精度时(逐向导航)才设置此项。对于“附近”查询,默认的
(false)网络定位通常已足够精确。
隐私注意事项
Section titled “隐私注意事项”- 不要在完成所需任务后继续存储原始坐标。
- 在触发提示前清晰披露位置用途——用户了解原因后授权率更高。
- 除非精度至关重要,否则优先使用粗略位置(
enableHighAccuracy: false)。
浏览器与生态支持
Section titled “浏览器与生态支持”当前各浏览器数据请参见 /compatibility/。
决策判定框架
Section titled “决策判定框架”| 决策问题 | 建议行为 | 理由 |
|---|---|---|
| 一次性位置查询? | 使用 getCurrentPosition,设合理的 timeout 与 maximumAge。 |
避免持续跟踪消耗;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 查询权限状态。