Как с помощью Dadata определить город по IP?

  • четверг, 5 декабря 2019 г. в 08:14:00

На работе потребовалось запилить задачу для автоматического определения города при совершении заказа. Было решено сделать это на фронте, ибо бек был занят.

Как известно, фронт не умеет определять IP и город. В первом случае, он без бека не сможет получить IP, во втором случае, ему нужно запрашивать разрешение на определение геолокации юзера, где всплывает бесящее окно с просьбой дать разрешение.

Метод костыльный, но рабочий (на 80%). Почему 80%? Дело в том, что точно определить город юзера практически невозможно и сервисы могут ошибаться. Например, я живу в г. Назрань, а мне выдает г. Сунжа (~30 км. от моего города).

Получение города и IP

Для того, чтобы определить город юзера, нужно определить его IP. Определить IP не сложно, есть множество бесплатных сервисов, например ipify.org. Также, нужно получить API-ключ от сервиса Dadata, чтобы работать с их API. После регистрации (там есть бесплатная), вы получите ключ. Пихните его в код ниже.

Можно также не передавать параметр ip и не отправлять лишний запрос для получения IP адреса.


_34
function 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
_34
getUserCity()
_34
.then(({ city, ip }) => {
_34
console.log(city, ip);
_34
})
_34
.catch(err => {
_34
console.log(err);
_34
});

Функция getUserCity возвращает объект с city и ip. Далее, вместо console.log, вы можете вставить эти данные, куда вам нужно. В итоге получаем:

#dadata#ip#geo#geolocation#city#гео#api