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?
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 wServerName
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!
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.
HTTP_HOST
tak długo, jak nieprawidłowe wartości pochodzące od złośliwego użytkownika nie mogą niczego zepsuć.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'
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.
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ę.
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ł.
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.
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).
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;
}
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