Jaka jest różnica między nazwą hosta HTTP A nazwą serwera w PHP?

Kiedy rozważyłbyś użycie jednego nad drugim i dlaczego?

Author: slick, 2010-02-19

9 answers

HTTP_HOST jest pobierany z nagłówka żądania HTTP i to jest to, czego klient faktycznie użył jako" host docelowy " żądania. {[2] } jest zdefiniowany w konfiguracji serwera. To, którego użyć, zależy od tego, do czego go potrzebujesz. Powinieneś teraz jednak zdać sobie sprawę, że jeden jest kontrolowana przez Klienta wartość, która może w ten sposób nie być wiarygodne do użytku w logice biznesowej, a drugi jest kontrolowana przez serwer wartość, która jest bardziej niezawodna. Musisz jednak upewnić się, że dany serwer WWW ma SERVER_NAME poprawnie skonfigurowany. Na przykład Apache HTTPD, oto wyciąg z jego dokumentacji :

Jeśli nie podano ServerName, Serwer próbuje wydedukować nazwę hosta, wykonując odwrotne wyszukiwanie na adresie IP. Jeśli w ServerName Nie podano portu, wtedy serwer użyje portu z przychodzącego żądania. Aby uzyskać optymalną niezawodność i przewidywalność, należy określić jawną nazwę hosta i portu za pomocą ServerName dyrektywa.


Update : po sprawdzeniu odpowiedzi Pekki na twoje pytanie , która zawiera link do odpowiedzi bobince , że PHP zawsze zwróci HTTP_HOST wartość dla SERVER_NAME, co jest sprzeczne z moim własnym PHP 4.x + Apache HTTPD 1.2.doświadczenia z XAMPP sprzed kilku lat, wydmuchałem trochę kurzu z mojego obecnego środowiska XAMPP na Windows XP (Apache HTTPD 2.2.1 z PHP 5.2.8), uruchomiłem go, stworzyłem stronę PHP, która drukuje obie wartości, stworzyłem Test aplikacji Java przy użyciu URLConnection modyfikowanie nagłówka Host i testy nauczyły mnie, że tak jest rzeczywiście (niepoprawnie).

Po pierwszym podejrzeniu PHP i przekopaniu się do niektórych raportów o błędach PHP dotyczących tematu, dowiedziałem się, że głównym problemem jest używany serwer WWW, że nieprawidłowo zwrócił nagłówek HTTP Host, gdy SERVER_NAME został poproszony. Więc wykopałem Apache HTTPD zgłoszenia błędów za pomocą różne słowa kluczowe dotyczące tematu i w końcu znalazłem powiązany błąd . Zachowanie to zostało wprowadzone od około Apache HTTPD 1.3. Musisz ustawić UseCanonicalName dyrektywa do on w <VirtualHost> wpis ServerName w httpd.conf (sprawdź również ostrzeżenie na dole dokumentu!).

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
</VirtualHost> 
To mi pomogło.

Podsumowując, SERVER_NAME jest bardziej niezawodny, ale jesteś zależny od konfiguracji serwera!

 730
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26

HTTP_HOST jest hostem docelowym wysłanym przez Klienta. Może być dowolnie manipulowany przez użytkownika. Nie ma problemu, aby wysłać zapytanie do witryny z prośbą o HTTP_HOST wartość www.stackoverflow.com.

SERVER_NAME pochodzi z definicji serwera VirtualHost i dlatego jest uważany za bardziej niezawodny. Można go jednak również manipulować z zewnątrz, pod pewnymi warunkami związanymi z konfiguracją serwera www: Zobacz to to pytanie która dotyczy aspektów bezpieczeństwa zarówno wariacje.

Nie powinieneś na nich polegać, by być bezpiecznym. To powiedziawszy, czego używać naprawdę zależy od tego, co chcesz zrobić. Jeśli chcesz określić, na której domenie działa twój skrypt, możesz bezpiecznie używać HTTP_HOST tak długo, jak nieprawidłowe wartości pochodzące od złośliwego użytkownika nie mogą niczego zepsuć.
 60
Author: Pekka 웃,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:36

Jak wspomniałem w ta odpowiedź , Jeśli serwer działa na porcie innym niż 80 (co może być powszechne na komputerze deweloperskim/intranetowym), to HTTP_HOST zawiera port, podczas gdy SERVER_NAME nie.

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'
W przeciwieństwie do większości serwerów wirtualnych, serwery wirtualne nie są dostępne w Apache.]}

Zauważ, że HTTP_HOST Czy nie zawiera :443 podczas uruchamiania na HTTPS(chyba że używasz niestandardowego portu, którego nie testowałem).

Jak zauważyli inni, oba również różnią się przy użyciu IPv6:

$_SERVER['HTTP_HOST'] == '[::1]'
$_SERVER['SERVER_NAME'] == '::1'
 45
Author: Simon East,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:42

Pamiętaj, że jeśli chcesz używać IPv6, prawdopodobnie chcesz używać HTTP_HOST zamiast SERVER_NAME. Jeśli wpiszesz http://[::1]/ Zmienne środowiskowe będą następujące:

HTTP_HOST = [::1]
SERVER_NAME = ::1

Oznacza to, że jeśli wykonasz na przykład mod_rewrite, możesz uzyskać paskudny wynik. Przykład przekierowania SSL:

# SERVER_NAME will NOT work - Redirection to https://::1/
RewriteRule .* https://%{SERVER_NAME}/

# HTTP_HOST will work - Redirection to https://[::1]/
RewriteRule .* https://%{HTTP_HOST}/

Dotyczy to tylko w przypadku dostępu do serwera bez nazwy hosta.

 25
Author: Daniel Marschall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-11 00:23:01

Jeśli chcesz sprawdzić przez serwer.php lub jak chcesz to nazwać z poniższym:

<?php

phpinfo(INFO_VARIABLES);

?>

Lub

<?php

header("Content-type: text/plain");

print_r($_SERVER);

?>

Następnie uzyskaj do niego dostęp z wszystkimi poprawnymi adresami URL dla swojej witryny i sprawdź różnicę.

 5
Author: stevewh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-03 10:17:15

Zależy, czego chcę się dowiedzieć. SERVER_NAME to nazwa hosta serwera, podczas gdy HTTP_HOST to wirtualny host, z którym Klient się połączył.

 4
Author: Rowland Shaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-19 15:31:32

Zajęło mi trochę czasu, aby zrozumieć, co ludzie mieli na myśli przez "{[0] } jest bardziej wiarygodne". Używam współdzielonego serwera i nie mam dostępu do dyrektyw wirtualnego hosta. Używam mod_rewrite w .htaccess do mapowania różnych HTTP_HOST do różnych katalogów. W takim przypadku to HTTP_HOST ma znaczenie.

Sytuacja jest podobna, jeśli używa się wirtualnych hostów opartych na nazwach: dyrektywa ServerName wewnątrz wirtualnego hosta po prostu mówi, która Nazwa hosta będzie mapowana do tego wirtualnego hosta. Najważniejsze jest to, że, w obu przypadkach nazwa hosta podana przez Klienta podczas żądania (HTTP_HOST) musi być dopasowana do nazwy serwera, która sama jest mapowana do katalogu. To, czy mapowanie odbywa się z dyrektywami wirtualnego hosta, czy z regułami htaccess mod_rewrite, jest tutaj drugorzędne. W takich przypadkach {[2] } będzie takie samo jak SERVER_NAME. Cieszę się, że Apache jest tak skonfigurowany.

Jednak sytuacja jest inna w przypadku hostów wirtualnych opartych na IP. W tym przypadku i tylko w tym przypadku, SERVER_NAME i HTTP_HOST może być inaczej, ponieważ teraz klient wybiera serwer po IP, a nie po nazwie.Rzeczywiście, mogą istnieć specjalne konfiguracje, w których jest to ważne.

Więc, począwszy od teraz, będę używać SERVER_NAME, na wypadek, gdyby mój kod został przeniesiony w tych specjalnych konfiguracjach.

 2
Author: Dominic108,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-11 00:31:18

Zakładając, że jeden ma prostą konfigurację (CentOS 7, Apache 2.4.x, oraz PHP 5.6.20) i tylko jedną stronę internetową (nie zakładając hostingu Wirtualnego)...

W sensie PHP, $_SERVER['SERVER_NAME'] jest elementem rejestrującym PHP w superglobalu $_SERVER opartym na konfiguracji Apache (**ServerName** z UseCanonicalName On) w httpd.conf (czy to z dołączonego pliku konfiguracyjnego wirtualnego hosta, cokolwiek, itp ...). HTTP_HOST pochodzi z nagłówka HTTP host. Traktuj to jako wejście użytkownika. Filtruj i sprawdzaj przed używam.

Oto przykład gdzie używam $_SERVER['SERVER_NAME'] jako podstawy do porównania. Poniższa metoda pochodzi z konkretnej klasy dziecięcej, którą stworzyłem o nazwie ServerValidator (child of Validator). ServerValidator sprawdza sześć lub siedem elementów w $_SERVER przed ich użyciem.

Przy określaniu, czy żądanie HTTP jest postem, używam tej metody.

public function isPOST()
{
    return (($this->requestMethod === 'POST')    &&  // Ignore
            $this->hasTokenTimeLeft()            &&  // Ignore
            $this->hasSameGETandPOSTIdentities() &&  // Ingore
            ($this->httpHost === filter_input(INPUT_SERVER, 'SERVER_NAME')));
}

Do czasu wywołania tej metody nastąpiłoby filtrowanie i Walidacja odpowiednich elementów $_SERVER (i odpowiednich właściwości set).

Linia ...

($this->httpHost === filter_input(INPUT_SERVER, 'SERVER_NAME')

... sprawdza, czy wartość $_SERVER['HTTP_HOST'] (ostatecznie pochodząca z żądanego nagłówka HTTP host) pasuje do $_SERVER['SERVER_NAME'].

Teraz używam superglobal speak, aby wyjaśnić mój przykład, ale to dlatego, że niektórzy ludzie nie są zaznajomieni z INPUT_GET, INPUT_POST, i INPUT_SERVER w odniesieniu do filter_input_array().

Najważniejsze jest to, że nie obsługuję żądań postów na moim serwerze, chyba żewszystkie {49]} cztery warunki są spełnione. Stąd, jeśli chodzi o POST żądania, brak podania nagłówka HTTP host (obecność testowana wcześniej) doom dla przeglądarek strict HTTP 1.0. Co więcej, żądany host musi odpowiadać wartości dla ServerName W httpd.conf , a przez rozszerzenie, wartość $_SERVER('SERVER_NAME') W $_SERVER superglobalu. Ponownie, używałbym INPUT_SERVER Z FUNKCJAMI PHP filter, ale łapiesz o co mi chodzi.

Należy pamiętać, że Apache często używa ServerName w standardzie przekierowania (takie jak pozostawienie końcowego ukośnika poza adresem URL: przykład, http://www.foo.com becoming http://www.foo.com/), nawet jeśli nie używasz przepisywania adresu URL.

Używam $_SERVER['SERVER_NAME'] jako standardu, a nie $_SERVER['HTTP_HOST']. Jest wiele tam iz powrotem na ten temat. $_SERVER['HTTP_HOST'] może być pusta, więc nie powinno to być podstawą do tworzenia konwencji kodu, takich jak moja metoda publiczna powyżej. Ale to, że oba mogą być ustawione nie gwarantuje, że będą równe. Testowanie jest najlepszym sposobem na upewnienie się (mając na uwadze wersję Apache i wersję PHP).

 2
Author: Anthony Rutledge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 15:41:10

Jak powiedział balusC SERVER_NAME nie jest niezawodny i można go zmienić w Apache config, konfiguracja nazwy serwera i firewalla, które mogą być między tobą a serwerem.

Następująca funkcja zawsze zwraca prawdziwy host (typowany przez użytkownika host) bez portu i jest prawie niezawodna:

function getRealHost(){
   list($realHost,)=explode(':',$_SERVER['HTTP_HOST']);
   return $realHost;
}
 0
Author: MSS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-20 13:21:26