Django搭配Apache2部署时ALLOWED_HOSTS配置不生效问题排查
问题描述
我在项目的settings.py文件中按如下方式配置了ALLOWED_HOSTS参数:
ALLOWED_HOSTS = [ 'localhost', 'semanticspace.io', 'www.semanticspace.io' ]
同时我也按如下规则配置了Apache2的ServerName相关参数:
... ServerName semanticspace.io ServerAlias www.semanticspace.io ...
完成上述配置后尝试访问站点网页时,仍抛出如下错误提示:
Invalid HTTP_HOST header: 'www.semanticspace.io'. You may need to add 'www.semanticspace.io' to ALLOWED_HOSTS.
请问导致该问题出现的可能原因是什么?
可能原因
按实际部署中出现概率从高到低排序:
- 应用未重载新配置:修改
settings.py后没有重启对应的Django进程。如果是mod_wsgi模式部署,仅reload Apache配置不一定会触发wsgi应用重载,需要全量重启Apache服务,或者手动touch项目根目录下的wsgi.py文件触发重载;如果是Apache反向代理Gunicorn/uWSGI的架构,必须重启后端的Gunicorn/uWSGI进程,仅重启Apache不会让后端Django加载新配置。 - 配置加载错误:
- 项目拆分了多环境settings文件,你修改的并非当前运行环境加载的配置文件,可以在报错页面查看
DJANGO_SETTINGS_MODULE环境变量值,确认实际加载的配置文件路径 settings.py中在你配置的ALLOWED_HOSTS语句之后,存在二次赋值覆盖了原有配置,把www.semanticspace.io条目移除了
- 项目拆分了多环境settings文件,你修改的并非当前运行环境加载的配置文件,可以在报错页面查看
- Host头实际值和配置不匹配:
- 站点未使用80/443默认端口时,请求到达Django的HTTP_HOST头会携带端口号(比如
www.semanticspace.io:8443),这种情况需要把带端口的完整域名加入ALLOWED_HOSTS才能通过校验 - 配置ALLOWED_HOSTS时条目里混入了不可见字符(比如中文空格、复制粘贴带的隐藏换行符),导致字符串实际值和请求头里的域名不匹配
- Apache反向代理未正确传递Host头,或者传递了带多余字符的异常Host值,可以临时在Django入口处打印
request.META.get('HTTP_HOST')查看实际收到的Host内容
- 站点未使用80/443默认端口时,请求到达Django的HTTP_HOST头会携带端口号(比如
- 请求被转发到错误实例:服务器上部署了多个Django应用,Apache的VirtualHost匹配优先级问题导致
www.semanticspace.io的请求被转发到了其他未配置该域名ALLOWED_HOSTS的Django实例上,可以检查反向代理的转发目标地址、VirtualHost的加载顺序确认。 - 中间件篡改请求头:项目启用的自定义中间件、第三方安全类中间件在ALLOWED_HOSTS校验逻辑执行前修改了
request.META['HTTP_HOST']的值,导致实际参与校验的Host值和预期不符。
内容的提问来源于stack exchange,提问作者cuneyttyler
相关产品推荐
相关产品推荐

