Браузеры фирмы Opera (десктопный в режиме Turbo, мобильные Mini и Mobile) используют прокси-сервера компании в Норвегии и других странах мира для сжатия трафика. Это очень удобно при плохой связи с Интернетом, особенно на мобильных телефонах. Но создает проблемы при попытке узнать IP-адрес подключившегося пользователя, например, для геолокации. Благо создатели браузера спешат нам на помощь. Специально для таких случаев они посылают нестандартизированный HTTP-загловок X-Forwarded-For, впервые внедренный для прокси-сервера Squid и впоследствии ставший стандартом де-факто для прокси. Формат заголовка:

X-Forwarded-For: {IP-адрес} [ , {IP-адрес} ]*

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

Для определения географического положения пользователя нужно брать последний адрес из перечисленных в заголовке X-Forwarded-For — адрес, с которого пользователь пришел на сервера Opera. Первый может вполне быть внутренним прокси-сервером домашней сети и пользы от него нам никакой. Последний адрес может быть адресом другого прокси, но тут уж ничего не поделаешь.

Т.е. чтобы определить IP пользователя:

  1. смотрим заголовок X-Forwarded-For,
  2. если есть берем последний адрес в списке,
  3. если нет, то берем IP-адрес подключения.

Или как-то так на PHP:


function getUserIp() {
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $forwarded = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        return trim(array_pop($forwarded));
    }
    return $_SERVER['REMOTE_ADDR'];
}

И да, полностью полагаться на геолокацию на основе IP неправильно и всегда нужно давать пользователю возможность свое местоположение уточнить.

Кстати, X-Forwarded-For не единственный заголовок, выставляемый прокси. Интернеты сообщают еще о существовании заголовков X-REAL-IP, VIA и других. Но Opera их не использует :)