Jaka jest różnica między tymi trzema zmiennymi Nginx $host
, $http_host
i $server_name
?
Mam regułę przepisywania, w której nie jestem pewien, której powinienem użyć:
location = /vb/showthread.php {
# /vb/showthread.php?50271-What-s-happening&p=846039
if ($arg_p) {
return 301 $scheme://$host/forum/index.php?posts/$arg_p/;
}
Szukam odpowiedzi, która nie mówi tylko „użyj zmiennej ___ w regule przepisywania”, ale także wyjaśnia teoretyczne różnice między nimi.
$scheme
i$host
...return 301 /forum/index.php?posts/$arg_p/;
działa dobrze.Location
nagłówku.Odpowiedzi:
Prawie zawsze powinieneś używać
$host
, ponieważ jest to jedyna gwarancja posiadania czegoś sensownego niezależnie od tego, jak zachowuje się klient użytkownika, chyba że potrzebujesz semantyki jednej z pozostałych zmiennych.Różnicę wyjaśniono w dokumentacji nginx :
$host
zawiera „w następującej kolejności: nazwa hosta z wiersza żądania, nazwa hosta z pola nagłówka żądania„ Host ”lub nazwa serwera pasująca do żądania”$http_host
zawiera zawartość pola nagłówka HTTP „Host”, jeśli była obecna w żądaniu$server_name
zawieraserver_name
wirtualny host, który przetworzył żądanie, tak jak zostało zdefiniowane w konfiguracji nginx. Jeśli aserver
zawiera wieleserver_name
s, tylko pierwsza będzie obecna w tej zmiennej.Ponieważ klienty użytkownika mogą wysyłać nazwę hosta w wierszu żądania, a nie w nagłówku Host:, choć jest to rzadko wykonywane, z wyjątkiem łączenia się z serwerami proxy, należy to uwzględnić.
Musisz także wziąć pod uwagę przypadek, w którym klient użytkownika w ogóle nie wysyła nazwy hosta, np. Stare żądania HTTP / 1.0 i nowoczesne źle napisane oprogramowanie. Możesz to zrobić, przekierowując je do hosta wirtualnego typu catch-all, który niczego nie obsługuje, jeśli obsługujesz wiele witryn internetowych lub jeśli masz tylko jedną witrynę internetową na serwerze, możesz przetwarzać wszystko za pośrednictwem jednego hosta wirtualnego . W tym drugim przypadku również musisz to uwzględnić.
Tylko
$host
zmienna uwzględnia wszystkie możliwe rzeczy, które klient użytkownika może zrobić podczas tworzenia żądania HTTP.źródło
$server_name
jest bezpieczny, gdyHost:
pole z UA może zawierać dowolną treść.Chciałbym dodać kolejny ważny punkt niewymieniony w zaakceptowanej odpowiedzi.
$host
czy nie mają numer portu, natomiast$http_host
zawierają numer portu.edycja : nie zawsze.
Zawsze ustawiam nagłówek „add_header Y-blog-http_host” $ http_host ”;”
Następnie
curl -I -L domain.com:80
(lub 443) i nagłówek w ogóle nie pokazuje numeru portu. Zweryfikowano za pomocą nginx-extra 1.10.3. Czy to dlatego, że jest to typowe porty http lub konfiguracja Nginx? Ten komentarz, żeby powiedzieć, że nie zawsze zachowuje się tak, jak myślisz.źródło
Zmagałem się również z tym przez jakiś czas. Stało się jasne, gdy zrozumiałem, że $ http_XXXXX odnosi się do wszystkich zadeklarowanych zmiennych nagłówka.
Tak więc $ http_user_agent, $ http_referer to „USER AGENT”, „REFERER” wymieniony małymi i małymi literami. To wyjaśniło mi, skąd do diabła pochodzi $ http_upgrade w wielu przykładach konfiguracji NGINX.
Przeczytaj to na https://stackoverflow.com/questions/15414810/whats-the-difference-of-host-and-http-host-in-nginx
źródło