Почему Request.build_absolute_uri приводит к localhost вместо реального домена?
У меня есть сайт, развернутый на Nginx и построенный на Django. Ссылка Request.build_absolute_uri там почему-то ведет не на реальный домен и ip, который к нему привязан, а на localhost:8080 из Waitress/gunicorn, на котором запущено приложение. Почему? Я пробовал Request.build_absolute_uri и request._current_scheme_host - оба ведут на localhost. Сейчас временно я просто использую прямой путь типа "domain.com", но это не очень удобное решение.
Не могли бы вы сообщить мне, как решить эту проблему?
После того, как я понял, что передача запросов по всему окружению только для построения полных урлов была беспорядочной, я переделал функцию, используемую для построения абсолютных урлов. Вы просто устанавливаете HOSTNAME
в настройках разное имя хоста для каждого окружения.
def build_base_uri():
return getattr(settings, "USED_PROTOCOL", "http://") + getattr(settings, "HOSTNAME", "localhost")
def build_absolute_url(url):
return build_base_uri() + url
Если вы хотите придерживаться методов request, я изучил исходный код этого приложения и вот как оно определяет хост, который будет использоваться в uri. (при условии, что у вас нет DEBUG
и ваши ALLOWED_HOSTS
настроены правильно)
class HttpRequest:
...
def _get_raw_host(self):
"""
Return the HTTP host using the environment or request headers. Skip
allowed hosts protection, so may return an insecure host.
"""
# We try three options, in order of decreasing preference.
if settings.USE_X_FORWARDED_HOST and (
'HTTP_X_FORWARDED_HOST' in self.META):
host = self.META['HTTP_X_FORWARDED_HOST']
elif 'HTTP_HOST' in self.META:
host = self.META['HTTP_HOST']
else:
# Reconstruct the host using the algorithm from PEP 333.
host = self.META['SERVER_NAME']
server_port = self.get_port()
if server_port != ('443' if self.is_secure() else '80'):
host = '%s:%s' % (host, server_port)
return host
В соответствии с этим проверьте в просмотре эти заголовки HTTP_X_FORWARDED_HOST
или HTTP_HOST
или SERVER_NAME
. Если эти заголовки по какой-то причине содержат localhost или отсутствуют, вы можете изучить вопрос в конфигурации nginx о передаче заголовков вниз.