Яка різниця між змінними Nginx $ host, $ http_host та $ server_name?


42

У чому різниця між цими трьома змінними Nginx $host, $http_hostі $server_name?

У мене є правило переписати, де я не впевнений, який з них я повинен використовувати:

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/;
        }

Я шукаю відповідь, яка не просто говорить "використовувати змінну ___ у вашому правилі переписування", але також пояснює теоретичні відмінності між ними.


Пізніше я зрозумів, що мені навіть не потрібно вказувати $schemeі $host... return 301 /forum/index.php?posts/$arg_p/;працює чудово.
Джефф Відман

Більшість веб-переглядачів працюватиме з відносною URL-адресою при переадресації, але стандарт ( w3.org/Protocols/rfc2616/rfc2616-sec14.html ) вимагає абсолютного URL у Locationзаголовку.
Cthulhu

Відповіді:


54

Ви майже завжди повинні користуватися $host, оскільки це єдине гарантоване щось розумне, незалежно від того, як поводиться агент-користувач, якщо вам конкретно не потрібна семантика однієї з інших змінних.

Різниця пояснюється в документації nginx :

  • $host містить "у цьому порядку пріоритетності: ім'я хоста з рядка запиту або ім'я хоста з поля заголовка запиту" Хост "або ім'я сервера, що відповідає запиту"
  • $http_host містить вміст поля заголовка HTTP "Хост", якщо він був присутній у запиті
  • $server_nameмістить server_nameвіртуальний хост, який обробив запит, як це було визначено в конфігурації nginx. Якщо a serverмістить кілька server_names, у цій змінній буде присутній лише перший.

Оскільки для користувальницьких агентів законним є надсилання імені хоста в рядку запиту, а не в заголовку Host: хоча це робиться рідко, за винятком підключення до проксі, вам доведеться це враховувати.

Вам також доведеться враховувати випадок, коли агент-користувач взагалі не надсилає ім'я хоста, наприклад стародавні запити HTTP / 1.0 та сучасне програмне забезпечення, яке погано написано. Ви можете зробити це, переадресувавши їх на віртуальний хост, який нічого не обслуговує, якщо ви обслуговуєте кілька веб-сайтів, або якщо у вас на сервері є лише один веб-сайт, ви можете обробити все через один віртуальний хост . В останньому випадку ви також повинні це враховувати.

Лише $hostзмінна обліковує всі можливі речі, які може зробити агент-користувач при формуванні HTTP-запиту.


2
З іншого боку, поле $server_nameбезпечно, коли Host:поле з UA може містити довільний вміст.
Cthulhu

1
Чи перейменовано $ http_host на $ ім'я хоста? Я не можу знайти таку змінну в Nginx doc. $ hostname - це найбільш схоже, напевне,.
darkbaby123

3
@ darkbaby123 Ні, його не перейменовували ні до чого. Дивіться документацію .
Майкл Хемптон

1
А тепер я розумію, що означає змінна http_ <ім'я>. Дякую!
darkbaby123

0

Я хотів би додати ще один важливий момент, який не згадується у прийнятій відповіді.

$hostробити НЕ мають номер порту, в той час як $http_hostDO включати номер порту.

редагувати : не завжди.

Я встановлюю заголовок "add_header Y-blog-http_host" $ http_host "завжди;"

Тоді curl -I -L domain.com:80(або 443) і заголовок взагалі не показує номер порту. Перевірено з nginx-extra 1.10.3. Це тому, що це звичайні порти http (s) або конфігурація nginx? Цей коментар просто для того, щоб сказати, що не завжди поводиться так, як ви думаєте.


0

Я також деякий час боровся з цим. Стало ясно, коли я зрозумів, що $ http_XXXXX стосується всіх оголошених змінних заголовків.

Тож $ http_user_agent, $ http_referer є "АГЕНТОМ ПОТРІБНИКА", "REFERER", з яким посилаються в нижньому регістрі та в нижньому регістрі. Це пояснило мені, звідки походить $ http_upgrade у багатьох зразках конфігурації NGINX.

Прочитайте його з https://stackoverflow.com/questions/15414810/whats-the-difference-of-host-and-http-host-in-nginx

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.