На работе потребовалось запилить задачу для автоматического определения города при совершении заказа. Было решено сделать это на фронте, ибо бек был занят.
Как известно, фронт не умеет определять IP и город. В первом случае, он без бека не сможет получить IP, во втором случае, ему нужно запрашивать разрешение на определение геолокации юзера, где всплывает бесящее окно с просьбой дать разрешение.
Метод костыльный, но рабочий (на 80%). Почему 80%? Дело в том, что точно определить город юзера практически невозможно и сервисы могут ошибаться. Например, я живу в г. Назрань, а мне выдает г. Сунжа (~30 км. от моего города).
Для того, чтобы определить город юзера, нужно определить его IP. Определить IP не сложно, есть множество бесплатных сервисов, например ipify.org. Также, нужно получить API-ключ от сервиса Dadata, чтобы работать с их API. После регистрации (там есть бесплатная), вы получите ключ. Пихните его в код ниже.
Можно также не передавать параметр ip и не отправлять лишний запрос для получения IP адреса.
_34function getUserCity() {_34 return new Promise((resolve, reject) => {_34 fetch('https://api.ipify.org?format=json')_34 .then(res => res.json())_34 .then(({ ip }) => {_34 fetch(_34 `https://suggestions.dadata.ru/suggestions/api/4_1/rs/iplocate/address?ip=${ip}&token=ВАШ_ТОКЕН_ДАДАТА`_34 )_34 .then(res => res.json())_34 .then(json => {_34 if (_34 {}.hasOwnProperty.call(json, 'family') &&_34 json.family.toLowerCase().indexOf('err')_34 ) {_34 return reject(json);_34 }_34 const {_34 location: {_34 data: { city },_34 },_34 } = json;_34 resolve({ city, ip });_34 });_34 });_34 });_34}_34_34getUserCity()_34 .then(({ city, ip }) => {_34 console.log(city, ip);_34 })_34 .catch(err => {_34 console.log(err);_34 });
Функция getUserCity возвращает объект с city и ip. Далее, вместо console.log
, вы можете вставить эти данные, куда вам нужно. В итоге получаем: