Docker部署Django+Nginx遇400错误:请求协议混淆排查
解决Django+Nginx反向代理的400 Bad Request错误
核心问题
Django开发服务器收到了HTTPS协议的请求标识,但它本身仅支持HTTP服务,导致协议不匹配报错。
解决方案
方案1:修改Nginx配置,强制传递HTTP协议头
将Nginx配置中的X-Forwarded-Proto头从$scheme改为固定的http:
upstream web_python { server web_python:8000; } server { listen 80; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 替换原有的$scheme为http proxy_set_header X-Forwarded-Proto http; proxy_set_header Host $host; proxy_redirect off; proxy_pass http://web_python; } }
修改后重启Nginx容器生效。
方案2:配置Django识别正确的转发协议
在Django项目的settings.py中添加以下配置,明确告诉Django信任反向代理传递的HTTP协议:
# 信任反向代理的X-Forwarded-Proto头 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'http')
同时检查以下配置是否符合开发环境要求:
- 确保
DEBUG = True - 若设置了
SECURE_SSL_REDIRECT = True,改为False(开发环境无需强制HTTPS) - 确认
ALLOWED_HOSTS包含Nginx请求中传递的Host值(比如localhost或你的测试域名)
原因说明
你的Nginx配置中使用了proxy_set_header X-Forwarded-Proto $scheme,$scheme会取外部请求的协议。如果你的外部访问(比如浏览器)使用了HTTPS(即使是本地自签名证书),这个变量会被设为https,传递给Django后,Django会认为这是HTTPS请求,但开发服务器runserver仅支持HTTP,因此抛出400错误。即使在容器内直接访问,若Django配置了强制HTTPS的选项(如SECURE_SSL_REDIRECT),也会触发同样的问题。
内容的提问来源于stack exchange,提问作者René Sánchez
相关产品推荐
相关产品推荐

