Использование freegeoip для списка IP-адресов
Пожалуйста, дайте мне простой совет, где копать!
У меня есть несколько IP-адресов, и мне нужно отобразить местоположение рядом с каждым из них.
У меня есть список IPS в массиве через
var table = document.createElement('table');
table.innerHTML = forext;
var ips = [].slice.call(table.querySelectorAll('a[href*="?ip="]')).map(anchor => anchor.textContent).join("\n");
8.8.8.8
8.8.4.4
...
Я могу получить местоположение каждого из них через поле ввода
$('.send').on('click', function(){
$.getJSON('https://ipapi.co/'+$('.ip').val()+'/json', function(data){
$('.city').text(data.city);
$('.country').text(data.country);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="ip" value="8.8.8.8">
<button class="send">Go</button>
<br><br>
<span class="city"></span>,
<span class="country"></span>
НО мне нужно распечатать IP-адреса и расположение рядом с ними:
Итак, у меня есть это:
8.8.8.8
8.8.8.8
НО мне это нужно
8.8.8.8 -Mountain View, US
8.8.8.8 -Mountain View, US
...
Как я могу обработать весь массив через http://freegeoip.net/json/? Спасибо.
Обновление 1: Попытка сделать это с помощью: ips[i]
var ipText='Lookup...';
var table = document.createElement('table');
table.innerHTML = forext;
var ips = [].slice.call(table.querySelectorAll('a[href*="?ip="]')).map(anchor => anchor.textContent).join("\n");
var ipLocations = [];
for(i=0;i<ips.length;i++){
$.getJSON('https:/freegeoip.net/json/' + ips[i], function(data) {
// could also use data.country_name, or any other property in the returned JSON
var outputString = data.ips[i] + ' - ' + data.city + ', ' + data.country_code;
ipLocations.push(outputString);
});
}
ipText = ipLocations.join('\n');
message.innerText = ipText;
1 ответ
Прежде всего, вы действительно хотите, чтобы ваши IP-адреса представляли собой массив строк, а не одну строку. Таким образом, вы должны изменить свою декларацию для var ips = ...
и удалите .join("\n")
с конца - это превращает ваш удобный список IP-строк в одну строку с IP-адресами, разделенными символами новой строки, которые вам не нужны.
Затем, когда у вас есть массив IP-адресов в форме что-то вроде ips = ['8.8.8.8', '8.8.4.4', ... ];
... тогда вы можете получить результат, который вы описали следующим образом:
var ipLocations = [];
for (var ip of ips) {
$.getJSON('https://freegeoip.net/json/' + ip, function(data) {
// could also use data.country_name, or any other property in the returned JSON
var outputString = data.ip + ' - ' + data.city + ', ' + data.country_code;
ipLocations.push(outputString);
});
}
Теперь у вас есть массив строк с IP-адресом + местоположение, как вы описали. Если вы теперь хотите превратить это в одну строку, вы можете сделать ipText = ipLocations.join('\n');
чтобы получить выходные строки, разделенные символами новой строки.
Если вы собираетесь выводить этот текст в HTML-документ, вы можете присоединиться к <br>
вместо \n
Есть много контекстов, в которых пробельные символы, такие как \n
будет проигнорировано, и вы получите все выходные данные в одной строке.
ОБНОВИТЬ:
В моем первоначальном ответе были некоторые очень глупые ошибки, главным из которых было то, что я смешал синтаксис Python и JavaScript (facepalm). Исправив их, этот код работает. При этом есть несколько предостережений, которые необходимо упомянуть, а также некоторые ошибки в вашем коде Обновления 1, которые вы должны постараться понять.
Во-первых, проблемы в вашем коде:
- Вы никогда не избавились от
.join("\n")
из строки 4, где вы определяетеips
так что это просто строка вместо массива строк. Это означает, что ваш цикл for фактически зацикливается на каждом отдельном символе вips
строка, а не полные IP-адреса. - Вы пытаетесь получить доступ
data.ips[i]
внутри петли.data
переменная содержит ответ JSON на ваш запрос AJAX, но автоматически преобразуется из строки JSON в реальный объект JavaScript с помощью jQuery. Он имеет только те свойства, которые включены в ответ. В этом случае ответ всегда имеетip
собственности, так что вы можете получить доступdata.ip
, Тем не мение,ips
переменная, которую вы создали--data.ips
не существует, поэтому вы не можете получить доступ к его индексам.- В качестве примечания, если вы использовали
for...of
синтаксис, у вас также будет переменная цикла с именемip
что вы можете использовать вместо Тем не менее, вы должны понимать, чтоip
а такжеdata.ip
не являются одной и той же переменной, даже если они всегда будут иметь одинаковое значение в этом случае.
- В качестве примечания, если вы использовали
- URL начинается с "https:/" вместо "https://". На самом деле это моя вина, я опечатал ее в своем первоначальном ответе>_>;
С этим из пути вы подняли очень важный момент в своем комментарии - функцию $.getJSON()
является асинхронным, поэтому (игнорируя другие проблемы) код, который вы написали в обновлении 1, вероятно, не будет выполнять то, что вы ожидаете. Код после звонка getJSON
будет продолжать работать, даже если ваш AJAX-запрос еще не получил ответа, поэтому, если вы сразу же получите доступ к ipLocs
В массиве он может содержать только некоторые выходные строки или даже быть пустым.
Я не собираюсь объяснять вам, как ждать неблокирующего кода, потому что это совершенно другой вопрос. Я также обеспокоен тем, что это только усложнит ситуацию, учитывая ваш очевидный уровень знакомства с JavaScript. Но если вам просто нужно быстрое решение, которое дает ожидаемые вами результаты, даже если это совсем не лучшая практика, вы можете использовать ajax
функция вместо getJSON
, Это позволяет вам явно указать jQuery отправлять ваш AJAX-запрос синхронно, что означает, что он будет ждать ответа, прежде чем продолжить выполнение вашего кода. Однако вы должны знать, что синхронные запросы могут временно блокировать ваш браузер, предотвращая любые другие действия, пока запрос не будет завершен. Эта версия будет выглядеть так:
var ipLocations = [];
for (var ip of ips) {
$.ajax({
url: 'https://freegeoip.net/json/' + ip,
async: false,
success: function(data) {
var outputString = data.ip + ' - ' + data.city + ', ' + data.country_code;
ipLocations.push(outputString);
}
});
}