Использование геолокации
Secure context: This feature is available only in secure contexts (en-US) (HTTPS), in some or all supporting browsers.
Geolocation API позволяет пользователю предоставлять своё местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.
Концепты и использование
Вы часто хотите получать информацию о местоположении пользователя в своём веб приложении, например, для отображения участка на карте, либо для того, чтобы показывать информацию, основанную на местоположении посетителя.
API геолокации может быть вызвано через Navigator.geolocation ; это заставит браузер пользователя вывести уведомление с запросом для доступа к текущему местоположению. Если его одобрят, то браузер сможет предоставить доступ ко всем возможностям по работе с информацией о местонахождении (например, GPS).
Тогда разработчику станут доступны несколько разных способов получения соответствующей информации:
- Geolocation.getCurrentPosition() : возвратит местоположение устройства
- Geolocation.watchPosition() (en-US): зарегистрирует функцию-обработчик, которая будет вызываться автоматически каждый раз, когда местоположение изменится, возвращая новые данные.
В обоих случая, методы принимают три аргумента:
- Обязательную колбэк-функцию при успехе: если удалось получить местоположение пользователя, то функция вызовется с объектом GeolocationPosition как одним параметром, предоставляющим доступ к данным о месторасположении.
- Необязательную колбэк-функцию при ошибке: если не удалось получить позицию, то колбэк-функция вызовется с объектом GeolocationPositionError как одним параметром, содержащим информацию о том, что пошло не так.
- Необязательный объект PositionOptions (en-US), который содержит надстройки получения данных о местоположении.
Интерфейсы
Главный класс этого API — содержит методы для получения текущего местоположения пользователя, наблюдает за его изменениями и удаляет функции-наблюдатели.
Предоставляет месторасположение пользователя. Экземпляр GeolocationPosition , полученный при успешном вызове одного из методов Geolocation , внутри колбэк-функции при успехе, содержит метку времени плюс экземпляр объекта GeolocationCoordinates .
Предоставлять координаты пользователя; Экземпляр GeolocationCoordinates содержит широту, долготу и прочую важную подобную информацию.
GeolocationPositionError возвращается при неуспешном вызове методов, содержащихся в Geolocation , внутри колбэк-функции при ошибке, содержит код ошибки и сообщение.
Точка входа в API. Возвращает экземпляр объекта Geolocation , из которого становятся доступны все функции и методы.
Словари
Спецификации
Specification |
---|
Geolocation API # geolocation_interface |
Совместимость с браузерами
BCD tables only load in the browser
Доступность
Так как местоположение, основанное на WiFi, часто предоставляется Google, API местоположения может быть не доступен в Китае. Вы можете использовать местных провайдеров, таких как Baidu, Autonavi или Tencent. Эти сервисы используют IP-адрес пользователя и/или приложение для предоставления наиболее точной позиции.
Смотрите также
- Использование API местоположения (en-US)
- API местоположения на w3.org
- Кто изменил моё местоположение? (Hacks блог)
Node.js: получить IP-адрес клиента
req.connection.remoteAddress, req.headers [‘x-forwarded-for’], req.ip, req.ips, что все это значит? Есть ли прямой способ просто получить IP-адрес клиента/пользователя-агента, делающего запрос на мой сайт в Node.js/Express? Я не понимаю все прокси-материалы или все различия между всеми свойствами объекта req. Кроме того, я не понимаю, что такое «доверенный прокси» для Express. Может кто-нибудь дать мне прямое объяснение тому, что разница между всеми этими свойствами, и ответить, как я могу просто получить IP-адрес клиента?
Sam 09 окт. 2013, в 10:19
Поделиться
Как насчет использования node-ipware согласно объяснению здесь .
un33k 03 нояб. 2014, в 02:33
Поделиться:
5 ответов
Лучший ответ
req.ip — это простой способ получить IP-адрес клиента в Express. Вы можете увидеть используемую им логику (которая включает захват первого элемента из массива прокси-адресов req.ips , где этот массив построен из заголовков x-forwarded-for ) здесь.
dankohn 09 окт. 2013, в 09:27
Поделиться
Не могли бы вы описать, что такое x-forwarded-for?
Sam 10 окт. 2013, в 21:32
Каждый прокси перед вашим сервером добавляет заголовок x-forwarded-for. Много дополнительной информации здесь: en.wikipedia.org/wiki/X-Forwarded-For
Dan Kohn 11 окт. 2013, в 02:14
// Get client IP address from request object ---------------------- getClientAddress = function (req) < return (req.headers['x-forwarded-for'] || '').split(',')[0] || req.connection.remoteAddress; >;
Svbaker 10 окт. 2013, в 11:58
Поделиться
И что держит req object, я имею в виду, что мы будем там предоставлять?
Sanjay Khadka 02 март 2015, в 05:29
Обратите внимание, что req.headers[‘x-forwarded-for’] легко манипулируется на ПК, если вы не разместили свой сервер Node.JS за доверенным и правильно настроенным прокси-сервером. Вы должны сначала проверить req.connection.remoteAddress по списку известных доверенных прокси-серверов, прежде чем уважать req.headers[‘x-forwarded-for’] .
Bryan Field 22 сен. 2015, в 01:44
Оцените ИЛИ и разделите дополнения. Это хорошо, если ваше приложение находится за балансировщиком нагрузки и / или слоем кэширования.
justinpage 18 май 2016, в 06:33
его возвращение ::ffff:127.0.0.1 для первого попадания и для каждого последующего попадания возвращает ::1 . Оба не являются надлежащими публичными IP-адресами и не могут извлекать местоположение из них. Помогите мне решить это. Спасибо Вам!
Dynamic Remo 13 апр. 2017, в 16:16
Показать ещё 2 комментария
function getClientIP(req)
Behnam Mohammadi 24 янв. 2017, в 14:59
Поделиться
Привет, я разместил app.enable(‘trust proxy’); в моем файле server.ts сразу после import < serverApi, createTodoApi >from ‘./backend/api’; app.get(‘/data.json’, serverApi); app.use(‘/api’, createTodoApi()); следующего кода import < serverApi, createTodoApi >from ‘./backend/api’; app.get(‘/data.json’, serverApi); app.use(‘/api’, createTodoApi()); и доступ к переменным req.ip в моем файле backend / api.ts. Где его возвращение ::ffff:127.0.0.1 , который не является действительным IP-адресом для извлечения местоположения из него. Ждем вашего ответа. Спасибо!
Dynamic Remo 13 апр. 2017, в 16:54
Как отмечали другие, из-за использования потенциального использования прокси, вы действительно должны использовать req.ip и НЕ использовать заголовок X-Forwarded-For, как это рекомендует многие люди. Пока вы правильно настроите прокси-сервер в качестве доверенного прокси, req.ip всегда будет возвращать IP-адрес конечного пользователя.
например. Если у вас был прокси-сервер, подключавшийся из 8.8.8.8, вы бы сделали:
var express = require('express'); var app = express(); app.set('trust proxy', '8.8.8.8');
Так как вы доверяете прокси-серверу, теперь это сделает так, что то, что передается в заголовке X-Forwarded-For, будет храниться в req.ip, но ТОЛЬКО, если оно происходит от одного из доверенных прокси.
Подробнее о доверенном прокси можно найти здесь.
Теперь, как отмечали другие в комментариях; особенно при разработке локально вы можете получить ip в формате «:: ffff: 127.0.0.1».
Чтобы всегда получать адрес IPv4, у меня есть:
getClientAddress = function (req) < return req.ip.split(":").pop(); >;
Как с помощью JS определить ip пользователя?
Хочу сделать так что бы JS определял Ip пользователя при запуске скрипта, но не знаю как это сделать. Подскажете?
Отслеживать
задан 6 мая 2019 в 10:02
51 1 1 серебряный знак 6 6 бронзовых знаков
только на сервере можно попробовать определить ip пользователя, однако можно послать запрос на сторонний сервис для этого
6 мая 2019 в 10:04
JS должен обратиться на какой нибудь сервер, например через ajax и сервер может сообщить ему с какого ip он получил запрос
6 мая 2019 в 10:06
И как это в коде написать?
6 мая 2019 в 10:08
@Ёжик тут код не пишут за вас. Тут поправляют ваши ошибки. Наработки есть ? В гугле хоть искали.
6 мая 2019 в 10:14
Конечно искал, я бы суда не обратился бы если бы нашел.
6 мая 2019 в 10:16
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Только на сервере можно попробовать определить публичный ip пользователя, однако можно послать запрос на сторонний сервис для этого
fetch('https://ipapi.co/json/') .then(d => d.json()) .then(d => document.querySelector('#ip').innerHTML = d.ip);
Отслеживать
ответ дан 6 мая 2019 в 10:14
Stranger in the Q Stranger in the Q
56.1k 10 10 золотых знаков 83 83 серебряных знака 136 136 бронзовых знаков
Спасибо огромное!
6 мая 2019 в 10:17
@Ёжик всегда пожалуйста
6 мая 2019 в 10:20
@StrangerintheQ благодаря WebRTC, очень легко получить локальный IP-адрес
6 мая 2019 в 10:22
@ДенисНебесный а толку от него? это в 50% случаев адрес машины в подсети не имеющей отношения к интернету
6 мая 2019 в 10:25
@StrangerintheQ хакерам удобно. Понятно какой ip (с большой долей вероятности) у роутера, что бы его ломать изнутри
6 мая 2019 в 10:31
function findIP(onNewIP) < var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; var pc = new myPeerConnection(< iceServers: [] >), noop = function() <>, localIPs = <>, ipRegex = /([0-9](\.[0-9])|[a-f0-9](:[a-f0-9]))/g, key; function ipIterate(ip) < if (!localIPs[ip]) onNewIP(ip); localIPs[ip] = true; >pc.createDataChannel(""); pc.createOffer(function(sdp) < sdp.sdp.split('\n').forEach(function(line) < if (line.indexOf('candidate') < 0) return; line.match(ipRegex).forEach(ipIterate); >); pc.setLocalDescription(sdp, noop, noop); >, noop); pc.onicecandidate = function(ice) < if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return; ice.candidate.candidate.match(ipRegex).forEach(ipIterate); >; > var ul = document.createElement('ul'); ul.textContent = 'Ваш IP: ' document.body.appendChild(ul); function addIP(ip) < console.log('Ваш IP: ', ip); var li = document.createElement('li'); li.textContent = ip; ul.appendChild(li); >findIP(addIP);
Использование Geolocation API
Secure context: This feature is available only in secure contexts (en-US) (HTTPS), in some or all supporting browsers.
Geolocation API позволяет пользователю предоставлять своё местоположение web-приложению, если пользователь согласится предоставить его. Из соображений конфиденциальности, у пользователя будет запрошено разрешение на предоставление информации о местоположении.
Объект геолокации
Если объект существует, функции определения местоположения доступны. Вы можете проверить это следующим образом:
if ("geolocation" in navigator) /* местоположение доступно */ > else /* местоположение НЕ доступно */ >
Получение текущего местоположения
Чтобы получить текущее местоположение пользователя, вы должны вызвать метод getCurrentPosition() . Это инициирует асинхронный запрос для обнаружения местоположения пользователя, и запрашивает аппаратные средства позиционирования, чтобы получить последнюю актуальную информацию. Когда местоположение определено, выполняется callback. По желанию вы можете указать вторую callback функцию для обработки ошибки, которая запустится в случае ошибки. Третий, опциональный параметр — объект с опциями, где вы можете настроить максимальное значение возвращаемых данных, время ожидания ответа на запрос, и, при желании, точность возвращаемых данных.
Примечание: По умолчанию getCurrentPosition() пытается вернуть результат так быстро, как это возможно, за счёт чего даёт не очень точный результат. Это может быть полезно, если вам нужно быстро получить ответ, при этом не важна точность. Устройства с GPS, например, могут пытаться скорректировать данные GPS около минуты и даже больше, поэтому в самом начале могут вернуться менее точные данные (местоположение IP или wifi-сети), полученные getCurrentPosition() .
.geolocation.getCurrentPosition(function (position) do_something(position.coords.latitude, position.coords.longitude); >);
Функция do_something() , в примере выше, будет вызвана лишь тогда, когда данные о местоположении будут получены.
Наблюдение за текущим местоположением
Если данные о местоположении меняются (либо устройство находится в движении, либо пришли более точные данные о геопозиции), вы можете указать callback функцию, которая будет вызывается при любом обновлении данных о местоположении. Это делается с использованием функции watchPosition() (en-US), которая имеет несколько входных параметров: getCurrentPosition() . Эта функция вызывается много раз, позволяя браузеру обновлять данные о текущей локации либо во время движения, либо после получения более точной информации о местоположении (после применения более точных приёмов). Функция, которая вызывается при ошибке, для getCurrentPosition() , при желании, может быть вызвана неоднократно.
var watchID = navigator.geolocation.watchPosition(function (position) do_something(position.coords.latitude, position.coords.longitude); >);
Метод watchPosition() (en-US) возвращает числовой ID, который может быть использован для идентификации наблюдателя за местоположением; используйте его вместе с методом clearWatch() (en-US), чтобы перестать получать новые данные о местоположении.
.geolocation.clearWatch(watchID);
Точная настройка отклика
getCurrentPosition() и watchPosition() (en-US) принимают колбэк-функцию при успехе, необязательную колбэк-функцию при ошибке и необязательный объект PositionOptions (en-US) .
Этот объект позволяет вам включить возможность определения позиции с высокой точностью, указать максимальное время кеширования значения позиции (при повторных запросах, пока время не вышло, вам будет возвращается кешированное значение; после браузер будет запрашивать актуальные данные), а также указать значение, устанавливающее интервал — как часто браузер должен пытаться получить данные о местоположении, прежде чем выйдет время.
Вызов watchPosition (en-US) может выглядит следующим образом:
function geo_success(position) do_something(position.coords.latitude, position.coords.longitude); > function geo_error() alert("Извините, нет доступной позиции."); > var geo_options = enableHighAccuracy: true, maximumAge: 30000, timeout: 27000, >; var wpid = navigator.geolocation.watchPosition( geo_success, geo_error, geo_options, );
Описание позиции
Местоположение пользователя содержится в экземпляре объекта GeolocationPosition , содержащего внутри экземпляр другого объекта — GeolocationCoordinates .
Экземпляр GeolocationPosition содержит только две вещи, свойство coords , внутри которого GeolocationCoordinates и свойство timestamp, внутри которого экземпляр DOMTimeStamp (en-US), предоставляющее метку времени, созданную при получении данные.
Экземпляр GeolocationCoordinates содержит некоторое количество свойств, двое из которых вы будете чаще всего использовать: latitude и longitude , которые помогут вам отобразить полученную позицию на карте. Поэтому многие колбэк-функции с успешным получением позиции выглядят очень просто:
function success(position) const latitude = position.coords.latitude; const longitude = position.coords.longitude; // Дальше код, который что-то делает с широтой(latitude) и долготой(longitude) >
Однако, вы также можете получить и другую информацию из объекта GeolocationCoordinates , такую как высота над уровнем моря, скорость, направление устройства и точные данные о высоте, долготе и широте.
Обработка ошибок
Callback-функция для ошибок, если она была передана в getCurrentPosition() или watchPosition() , ожидает экземпляр объекта GeolocationPositionError в качестве первого аргумента. Он будет содержать два свойства, code , который укажет на то, какая именно ошибка произошла и понятное для человека message , описывающее значение поля code.
Функция может выглядеть примерно так:
function errorCallback(error) alert("ERROR(" + error.code + "): " + error.message); >
Примеры
Следующий пример использует Geolocation API для того, чтобы получить широту и долготу пользователя. При успешном выполнении, ссылка будет вести на openstreetmap.org , который отобразит пользовательскую позицию на карте.
body padding: 20px; background-color: #ffffc9; > button margin: 0.5rem 0; >
HTML
button id="find-me">Show my locationbutton>br /> p id="status">p> a id="map-link" target="_blank">a>
JavaScript
function geoFindMe() const status = document.querySelector("#status"); const mapLink = document.querySelector("#map-link"); mapLink.href = ""; mapLink.textContent = ""; function success(position) const latitude = position.coords.latitude; const longitude = position.coords.longitude; status.textContent = ""; mapLink.href = `https://www.openstreetmap.org/#map=18/$latitude>/$longitude>`; mapLink.textContent = `Широта: $latitude> °, Долгота: $longitude> °`; > function error() status.textContent = "Невозможно получить ваше местоположение"; > if (!navigator.geolocation) status.textContent = "Geolocation не поддерживается вашим браузером"; > else status.textContent = "Определение местоположения…"; navigator.geolocation.getCurrentPosition(success, error); > > document.querySelector("#find-me").addEventListener("click", geoFindMe);