Номер телефона

Последнее обновление:

Как проверить на какой сервер посылается веб-запрос?

При разработке веб-приложений, сайтов нередко возникает задача: определить, на какой сервер происходит веб-запрос: в сеть интернет или жена локальный сервер? Пользователю, конечно, в этом убедиться достаточно просто: надо всего лишь выключить соединение с интернетом и затем обновить вебстраницу. Если после этого она вновь будет, как ни в чем ни бывало, показана в браузере, значит, браузер взаимодействует с локальным сайтом. А вот как сделать подобную проверку программно, как вебстраница может сама определить с каким именно сервером происходит взаимодействие, на какой именно сервер отправляются запросы? На тот, который находится на компьютере пользователя (т.е. на локальный сервер) или же в сеть интернет?

Напомним, что локальные серверы используются, в частности, для отладки работы сайтов и отдельных вебстраниц. Но, также они могут использоваться, например, для реализации "прокладок", т.е. прокси-серверов.

Т.е. вебстраница как-то сама, без вмешательства пользователя, должна определять, на какой именно сервер направляется запрос. Здесь могут использоваться, в целом, два основных подхода.

1. Подход

Использование соответствующих сервисов в интернет-сети. Например, это - такие сервисы, как ip-address.ru, 2ip.ru и многие другие. Аналогичный сайт можно сделать и запустить на локальном сервере, т.е. на своем компьютере. И если вебстраница сделает AJAX-запрос на подобный сервис, то он вернет ей ее IP-адрес. И тут зависит от того, куда будет направлен запрос. Если у пользователя на компьютере подключен интернет и одновременно запущен локальный сервер, то есть два возможных варианта, куда пойдет запрос. Если он пойдет в интернет, то соответствующий сервер вернет браузеру, собственно, его IP-адрес в интернете. Который, напомним, может меняться, если пользователь не обладает так называемым "белым", т.е. фиксированным адресом. Обычно фиксированные IP-адреса предоставляются пользователям провайдерами за дополнительную оплату.

А если же запрос пойдет на локальный сервер, то браузер в качестве IP-адреса получит что-то вроде 127.0.0.1. Т.е. локальный адрес. Анализируя ответ сервера, можно легко отличить, куда был направлен запрос.

Отметим, что направление веб-запроса задается на уровне сетевых протоколов модели OSI; браузер, если не делать специальных настроек, полагается на сетевые настройки операционной системы (в том числе, с учетом настроек VPN), в которой он запущен.

Этот подход является универсальным, с одной стороны. Но, с другой, он требует наличия сайта, одноименного с аналогичным сервисом, у пользователя на локальном компьютере. Это, как правило, легко для профессионального разработчика, а вот для обычного пользователя, не связанного с вебразработкой и не имеющего понятия о серверах, такой подход неприменим. Да и едва ли он станет выполнять чьи-то рекомендации и устанавливать у себя некий сервер, одноименный с сервисом определения IP-адресов.

2. Подход

Использование веб-запроса на ресурс, достоверно имеющийся на сервере в интернете и достоверно отсутствующим у пользователя на компьютере. Ну, или, наоборот. Например, это может быть небольшой, буквально объемом в несколько байт, рисунок. Контролируя результат его загрузки (успех или ошибка) можно легко выяснить, на какой сервер (сетевой или локальный) был произведен запрос.

Рассмотрим такой код на javascript:

 // Функция устанавливает, на локальном ли сервере производится обработка запросов
function check_LOCAL_SERVER() {
if(document.body.hasAttribute('data-local_server')){
return result(1);
}else {
var test_img = document.createElement('div');
test_img.innerHTML = "<img src = '/pict.png' />"; // Этот рисунок имеется только на локальном сервере, его нет в интернете
// document.body.appendChild(test_img)
test_img.getElementsByTagName('img')[0].onload = function () {
document.body.setAttribute('data-local_server', 'yes');
result(0);
};
test_img.getElementsByTagName('img')[0].onerror = function () {
document.body.setAttribute('data-local_server', 'no');
result(0);
};
console.log('Unknown...');
return null;
}

function result(flag){
if(!flag){
test_img.getElementsByTagName('img')[0].onload = null; // Удаляем обработчики событий (чтобы не загромождать
test_img.getElementsByTagName('img')[0].onerror = null;// оперативную память), т.к. они более не нужны
}
console.log('Is server local, not internet? ' + document.body.getAttribute('data-local_server'));
return document.body.getAttribute('data-local_server');
}
}
document.body.onclick = function () {
alert('Is server local, not internet? '+ check_LOCAL_SERVER());
};

Контрольным рисунком является, в данном случае, pict.png. Который отсутствует в корневом каталоге соответствующего сайта (вебстраница которого просматривается пользователем), но который достоверно есть у пользователя на компьютере. Понятно, что можно сделать и наоборот: напротив, разместить этот рисунок на сервере в интернете, зная точно, что на компьютере пользователя такого рисунка нет. Это может быть рисунок с неким "сложным", уникальным именем.

Немного пояснений

Суть в том, что функция check_LOCAL_SERVER создает атрибут с именем data-local_server в теге <body> вебстраницы. Вы можете, разумеется, взять какое-то другое имя этого атрибута, но главное, чтобы его имя было уникальным, чтобы оно не использовалось другими скриптами, работающими на этой вебстранице.

Изначально, после запуска и отображения страницы браузером, эта функция проверяет наличие указанного атрибута. Его, естественно, пока еще нет, поэтому создается временный div, цель которого - попытаться загрузить в себя рисунок с указанным именем. Если загрузка будет успешной (это будет, в частности, когда рисунок присутствует на сервере), то сработает событие onload. В случае же отсутствия рисунка, сервер вернет ошибку 404 и сработает событие onerror. В зависимости от этого, будет установлен атрибут data-local_server в document.body с соответствующим значением и будет вызвана функция result. После этого уже любой скрипт, обратившийся к данному атрибуту и прочитавший его значение, будет знать, получен ли был рисунок с сервера или нет. Следовательно, скрипт будет знать, на какой сервер (локальный или интернетный) был направлен запрос на получение этого рисунка и, следовательно, и все другие запросы в рамках текущей сессии.

Отметим, что при плохом, некачественном сетевом соединении могут быть коллизии и запрос вместо сервера в интернете в итоге пойдет на локальный сервер.

Для наглядности, нижние строчки приведенного JS-кода задают обработчик клика на теге <body>. Для тестирования данного скрипта. В реальном проекте это, скорее всего, не понадобится. Кликая мышью где-нибудь на странице, можно будет видеть ответ (в окошке alert), с локального ли сервера произведен был запрос или нет.

Отметим, что после самого первого клика ответ будет неопределенным, т.е. null. Это вызвано тем фактом, что ответ выводится практически сразу после клика, не дожидаясь ответа сервера. Т.е. окно alert  с сообщением возникнет ДО момента ответа сервера. И в тег <body> еще ничего не успеет записаться, параметра data-local_server там еще не будет, т.е. его значение пока - не определено.

Также стоит посмотреть сообщения в консоли браузера.

Однако, через короткое время сервер таки ответит и, в зависимости от результата такого ответа, обработчик запишет в тег <body> параметр data-local_server с тем или иным значением ("yes" или "no"). Поэтому все последующие срабатывания обработчика, в результате кликов мыши, будут использовать уже это значение.

Пример - демонстрационный, но его вполне можно приспособить конкретно для своих нужд.

Когда это может быть нужным?

Например, при разработке веб-приложений, который используют ресурсы, хранящиеся на стороне клиента (т.е. на компьютере пользователя). Также это может быть полезным при разработке разного рода обслуживающих программ, систем, которые должна запускаться именно с компьютера пользователя, но не с сервера.

Какой подход является более эффективным?

В какой-то мере, более оптимальным и эффективным является 1-й подход. Потому, что он более результативен, в том числе, и в условиях сетевого соединения плохого качества. Когда непонятно (это если говорить о 2-м подходе), чем вызвана ошибка 404 при запросе рисунка клиентом (браузером): то ли и в самом деле его отсутствием на сервере, то ли сетью плохого качества. Правда, для более тщательного анализа ситуации можно дополнительно использовать, скажем, событие onreadystatechange. Которое позволяет контролировать не только конечный результат (да или нет, успех или неудача), но и промежуточные стадии обработки сетевого запроса. Ну, а также можно дополнительно анализировать код ошибки, возвращаемый сервером.

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



Комментарии:
Всего комментариев:0
Пожалуйста, не забудьте ознакомиться с правилами оставления комментариев.



Подписаться на комментарии на этой странице

Мы можем выполнить

Другие услуги
Интересная и полезная
информация
НАПИШИТЕ НАМ
Яндекс.Метрика
Номер телефона
© Copyright Все права защищены 2013-2024 Научный консалтинг