В чем разница между тремя переменными 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/;
}
Я ищу ответ, который не просто говорит «используйте переменную ___ в вашем правиле перезаписи», но также объясняет теоретические различия между ними.
Вы должны почти всегда использовать $host
, так как это единственный гарантированно иметь что-то разумное, независимо от того, как ведет себя пользовательский агент, если только вам не нужна семантика одной из других переменных.
Разница объясняется в документация nginx:
$host
содержит "в этом порядке приоритета: имя хоста из строки запроса или имя хоста из поля заголовка запроса 'Host', или имя сервера, соответствующее запросу"$http_host
содержит содержимое поля заголовка HTTP "Host", если оно присутствовало в запросе$server_name
содержит server_name
виртуального хоста, обработавшего запрос, как это было определено в конфигурации nginx. Если server
содержит несколько server_name
s, в этой переменной будет присутствовать только первый.Поскольку пользовательские агенты могут отправлять имя хоста в строке запроса, а не в заголовке Host :, хотя это делается редко, кроме случаев подключения к прокси, вы должны это учитывать.
Вы также должны учитывать случай, когда пользовательский агент вообще не отправляет имя хоста, например древние запросы HTTP / 1.0 и современное плохо написанное программное обеспечение. Вы можете сделать это, перенаправив их на универсальный виртуальный хост, который ничего не обслуживает, если вы обслуживаете несколько веб-сайтов или если у вас есть только один веб-сайт на вашем сервере, вы можете обрабатывать все через один виртуальный хост. . В последнем случае это тоже нужно учитывать.
Только $host
переменная учитывает все возможные действия, которые пользовательский агент может делать при формировании HTTP-запроса.
Я тоже некоторое время боролся с этим. Стало ясно, когда я понял, что $ http_XXXXX относятся ко всем объявленным переменным заголовка.
Итак, $ http_user_agent, $ http_referer - это "USER AGENT", "REFERER", указанные в нижнем регистре и с косой чертой. Это объяснило мне, откуда, черт возьми, $ http_upgrade во многих примерах конфигурации NGINX.
Прочтите это из https://stackoverflow.com/questions/15414810/whats-the-difference-of-host-and-http-host-in-nginx
Я хотел бы добавить еще один важный момент, не упомянутый в принятом ответе.
$host
делать НЕ есть номер порта, а $http_host
включает номер порта.
редактировать: не всегда.
Я установил заголовок "add_header Y-blog-http_host" $ http_host "always;"
затем curl -I -L domain.com:80
(или 443), а в заголовке вообще не отображается номер порта. Проверено с помощью nginx-extra 1.10.3. Это потому, что это общие порты http (s) или конфигурация nginx? Этот комментарий просто сказать, что не всегда веди себя так, как думаешь.