必须设为True,否则SECURE_SSL_REDIRECT不生效;Django依赖SECURE_PROXY_SSL_HEADER识别HTTPS,需Nginx透传X-Forwarded-Proto头,且仅对非POST请求全站重定向,DEBUG=True时自动禁用。

必须设为 True,否则 SECURE_SSL_REDIRECT 不生效。Django 本身不处理 TLS 终止,它只检查请求是否走 HTTPS —— 如果没走,就 301 重定向。但前提是它得“知道”当前是 HTTPS 环境,否则永远认为是 HTTP,也就永远不会跳转。
为什么 SECURE_SSL_REDIRECT = True 却没跳转?
常见原因不是配置写错了,而是 Django 根本收不到原始的 HTTPS 信息:
- 反向代理(如 Nginx、Cloudflare)没把
X-Forwarded-Proto: https头传给 Django -
SECURE_PROXY_SSL_HEADER没配,或配错字段名/值 - 开发环境直接用
runserver(不支持 HTTPS),又没关掉该配置 - 浏览器缓存了之前的 HTTP 301 重定向,导致反复跳回 HTTP(可清缓存或用隐身窗口测试)
SECURE_PROXY_SSL_HEADER 怎么配才安全?
这个配置本质是告诉 Django:“当收到某个特定 HTTP 头时,就信它是 HTTPS”。它不是自动识别,必须显式声明:
- 推荐写法:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') - Nginx 需同步加:
proxy_set_header X-Forwarded-Proto $scheme; - 绝不能写成
('HTTP_X_FORWARDED_PROTO', 'http')或漏掉引号 - 如果用了多层代理(比如 CDN + Nginx),确保最外层也透传该头,否则中间某层可能覆盖或丢弃
开启后哪些 URL 会被强制跳转?
SECURE_SSL_REDIRECT 是全站级的,但有明确例外:
立即学习“Python免费学习笔记(深入)”;
- 仅对非 POST 请求生效(GET、HEAD、OPTIONS 等);POST 请求不重定向,避免数据丢失
- DEBUG = True 时自动禁用,防止开发时反复跳转
- 不处理静态文件(
STATIC_URL)和媒体文件(MEDIA_URL)路径,它们由 Web 服务器直接服务 - 如果用了
ALLOWED_HOSTS且域名不匹配,重定向可能失败并抛出DisallowedHost错误
最容易被忽略的是:哪怕你只在生产环境启用,也得确认 settings.py 中没有其他地方(比如条件导入、环境变量覆盖)悄悄把 SECURE_SSL_REDIRECT 设回 False,或者把 DEBUG 意外设为 True。这类问题往往查半天才发现是环境变量拼错了一个字母。


















