JavaScript Geolocation API
Полное руководство по JavaScript Geolocation API: проверка поддержки, получение координат, отслеживание позиции и обработка ошибок.
Geolocation API позволяет веб-странице запросить у браузера местоположение устройства пользователя. С разрешения пользователя вы получаете координаты (широту и долготу), которые можно использовать для отображения ближайших результатов, центрирования карты или добавления геометки к контенту. Это руководство охватывает весь API: проверку поддержки, однократное получение текущей позиции, отслеживание изменений позиции со временем, параметры управления точностью и временем ожидания, а также правильную обработку ошибок и разрешений.
Введение в Geolocation API
Geolocation API является частью среды браузера (объект navigator), а не самого языка JavaScript. Если вы не знакомы с различием между возможностями языка и API, предоставляемыми браузером, обратитесь к главе Среда браузера, спецификации для получения контекста.
API предоставляет три метода на объекте navigator.geolocation:
getCurrentPosition()— получить позицию однократно.watchPosition()— получать позицию многократно по мере перемещения устройства.clearWatch()— остановить подпискуwatchPosition().
Два обязательных требования
- Безопасный контекст. Браузеры предоставляют геолокацию только для страниц, обслуживаемых по HTTPS (или
localhostво время разработки). На обычной страницеhttp://navigator.geolocationможет отсутствовать или каждый вызов завершится ошибкой. Это мера обеспечения конфиденциальности и безопасности. - Разрешение пользователя. Браузер показывает запрос при первом обращении страницы к геолокации. Ничего не происходит, пока пользователь не нажмёт Разрешить. Если он выберет Заблокировать, обратный вызов ошибки сработает с кодом
PERMISSION_DENIED.
Проверка доступности API
Всегда проверяйте наличие API перед использованием, поскольку старые браузеры и незащищённые страницы могут не предоставлять его.
Получение текущей позиции
Чтобы однократно получить местоположение устройства, вызовите getCurrentPosition(success, error, options). Обязателен только первый аргумент.
const options = {
// Ask for the highest-accuracy position available (e.g. GPS on mobile).
enableHighAccuracy: true,
// Give up after 5 seconds if no position is returned.
timeout: 5000,
// Never use a cached position; always fetch a fresh one.
maximumAge: 0
};
function success(position) {
const { latitude, longitude, accuracy } = position.coords;
console.log(`Latitude: ${latitude}, Longitude: ${longitude}`);
console.log(`Accurate to within ${accuracy} meters`);
}
function error(err) {
console.error(`Error (${err.code}): ${err.message}`);
}
navigator.geolocation.getCurrentPosition(success, error, options);Объект position
Обратный вызов успеха получает объект GeolocationPosition с двумя полями:
position.timestamp— время снятия показаний (миллисекунды с начала эпохи).position.coords— объектGeolocationCoordinates, содержащий:
| Свойство | Описание |
|---|---|
latitude | Градусы северной/южной широты (десятичные). |
longitude | Градусы восточной/западной долготы (десятичные). |
accuracy | Точность latitude/longitude в метрах. |
altitude | Высота над уровнем моря в метрах (или null). |
altitudeAccuracy | Точность altitude в метрах (или null). |
heading | Направление движения в градусах по часовой стрелке от севера (или null). |
speed | Скорость перемещения в метрах в секунду (или null). |
Поля heading и speed обычно заполняются только на устройствах, которые действительно движутся и оснащены соответствующими датчиками.
Объект options
Все три параметра необязательны. Выбирайте их исходя из вашего сценария использования:
| Параметр | По умолчанию | Описание |
|---|---|---|
enableHighAccuracy | false | При значении true запрашивает наиболее точный источник данных (GPS). Работает медленнее и расходует больше заряда батареи. |
timeout | Infinity | Максимальное количество миллисекунд ожидания перед вызовом обратного вызова ошибки с кодом TIMEOUT. |
maximumAge | 0 | Допустимый возраст кешированной позиции (в мс), по истечении которого требуется получение свежей. Используйте большее значение, чтобы повторно использовать недавние данные и ускорить ответ. |
Типичный компромисс: задайте enableHighAccuracy: false и ненулевое maximumAge, если достаточно приблизительного быстрого результата (например, «магазины рядом со мной»); используйте enableHighAccuracy: true с maximumAge: 0 для навигации с пошаговыми инструкциями.
Обработка ошибок
При сбое запроса обратный вызов ошибки получает объект GeolocationPositionError. Его свойство code точно указывает, что пошло не так:
function error(err) {
switch (err.code) {
case err.PERMISSION_DENIED: // 1
console.error("User denied the request for location.");
break;
case err.POSITION_UNAVAILABLE: // 2
console.error("Location information is unavailable.");
break;
case err.TIMEOUT: // 3
console.error("The request to get location timed out.");
break;
default:
console.error(`An unknown error occurred: ${err.message}`);
}
}PERMISSION_DENIED(1) — пользователь заблокировал доступ к местоположению, либо страница не находится в безопасном контексте.POSITION_UNAVAILABLE(2) — устройство не смогло определить своё местоположение (нет сигнала GPS/Wi-Fi и т. д.).TIMEOUT(3) — позиция не была получена в течение установленного вамиtimeout.
Предварительная проверка разрешения
Вы можете проверить разрешение на геолокацию без запуска запроса, используя Permissions API. Это полезно для настройки интерфейса (например, скрытия кнопки «Найти меня», если доступ уже заблокирован).
navigator.permissions.query({ name: "geolocation" }).then((result) => {
// result.state is "granted", "prompt", or "denied"
console.log(`Geolocation permission: ${result.state}`);
});Непрерывное отслеживание позиции
Для отслеживания в реальном времени watchPosition() вызывает ваш обратный вызов успеха каждый раз, когда изменяется позиция устройства. Метод возвращает числовой идентификатор наблюдения, который передаётся в clearWatch() для остановки отслеживания — если его не очистить, геолокация останется активной и будет разряжать батарею.
const watchID = navigator.geolocation.watchPosition(success, error, options);
// success() now fires every time the position updates.
// Later, when tracking is no longer needed:
navigator.geolocation.clearWatch(watchID);Если ваше отслеживание зависит от поворота экрана между книжной и альбомной ориентацией, Screen Orientation API хорошо сочетается с геолокацией в картографических приложениях.
Полный пример: отображение местоположения на карте
В этом примере используется Geolocation API для получения ваших координат и библиотека Leaflet.js для их отображения на слое OpenStreetMap.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Your Location on a Map</title>
<link
rel="stylesheet"
href="https://unpkg.com/[email protected]/dist/leaflet.css"
/>
</head>
<body>
<h1>Your Location on a Map</h1>
<div id="map" style="height: 400px"></div>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
const map = L.map("map").setView([lat, lon], 13);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution: "© OpenStreetMap contributors",
}).addTo(map);
L.marker([lat, lon])
.addTo(map)
.bindPopup("You are here!")
.openPopup();
});
} else {
document.getElementById("map").textContent =
"Geolocation is not supported by your browser.";
}
});
</script>
</body>
</html>При загрузке страницы она немедленно запросит ваше местоположение и отобразит маркер на карте в вашей позиции с всплывающим сообщением «You are here!». Это наглядное представление помогает понять, как веб-сайты могут взаимодействовать с географическими данными для улучшения пользовательского опыта.
Рекомендации
- Всегда проверяйте наличие API и обслуживайте страницы по HTTPS, иначе все вызовы завершатся ошибкой.
- Запрашивайте геолокацию только тогда, когда пользователь этого ожидает — например, после нажатия кнопки «Найти меня» — чтобы запрос разрешения имел понятный контекст.
- Обрабатывайте все коды ошибок и показывайте полезную альтернативу (например, поиск по адресу вручную) при отказе в разрешении.
- Вызывайте
clearWatch(), как только непрерывное обновление больше не нужно, чтобы экономить заряд батареи. - Выбирайте параметры осознанно: высокая точность для навигации, ненулевое
maximumAgeдля быстрого поиска «рядом со мной».
Заключение
Geolocation API предоставляет веб-приложениям конфиденциальный способ считывания местоположения пользователя через три метода: getCurrentPosition() для однократного чтения, watchPosition() для отслеживания в реальном времени и clearWatch() для остановки. В сочетании с обдуманным выбором параметров и правильной обработкой ошибок он обеспечивает работу карт, локального поиска и других функций с привязкой к местоположению. Для дальнейшего изучения связанных API браузера исследуйте Screen Orientation API и главу Среда браузера, спецификации.