Django DRF项目HTTPS下混合内容警告问题求助
Django DRF Docker部署混合内容问题解决
我将Django REST Framework(DRF)项目部署在Docker环境中,站点可通过HTTPS正常加载,但图片、视频等资源仍以HTTP方式加载,触发Mixed Content警告,即便已配置SSL证书,浏览器仍显示站点不安全。以下是相关配置文件:
mysite.conf(宿主机Nginx配置)
server { server_name cp.mysite.com; location / { proxy_pass http://127.0.0.1:3180; # docker container listens here proxy_read_timeout 3600s; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/cp.mysite.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/cp.mysite.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = cp.mysite.com) { return 301 https://$host$request_uri; } # managed by Certbot server_name cp.mysite.com www.cp.mysite.com; listen 80; return 404; # managed by Certbot }
docker nginx.conf(容器内Nginx配置)
upstream django { server django:5000; } server { listen 80; location / { proxy_pass http://django; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Host $host; client_max_body_size 100M; proxy_redirect off; } location /media/ { alias /usr/share/nginx/media/; } }
settings.py(Django配置)
SESSION_COOKIE_HTTPONLY = True CSRF_COOKIE_HTTPONLY = True X_FRAME_OPTIONS = "DENY" SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") SECURE_SSL_REDIRECT = env.bool("DJANGO_SECURE_SSL_REDIRECT", default=True) SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True SECURE_HSTS_SECONDS = 518400 SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True ) SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True) SECURE_CONTENT_TYPE_NOSNIFF = env.bool( "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True )
问题根源与修复方案
核心原因
页面通过HTTPS加载,但媒体资源URL仍为HTTP,这是因为Django生成资源链接时未识别到当前是HTTPS环境,或Nginx未正确传递协议信息。
修复步骤
- 修正Django媒体URL配置
在settings.py中明确指定HTTPS协议的媒体URL:
USE_X_FORWARDED_HOST = True # 替换为你的实际域名 MEDIA_URL = "https://cp.mysite.com/media/"
如果用环境变量管理,可改为:
MEDIA_URL = env.str("DJANGO_MEDIA_URL", default="https://cp.mysite.com/media/")
- 宿主机Nginx补充协议头
在mysite.conf的location /块中添加X-Forwarded-Proto头,确保Django获取正确的请求协议:
proxy_set_header X-Forwarded-Proto $scheme;
修改后的location块:
location / { proxy_pass http://127.0.0.1:3180; proxy_read_timeout 3600s; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 新增此行 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; }
- 容器内Nginx优化媒体资源响应
在docker nginx.conf的/media/location块中添加HSTS头,强制浏览器用HTTPS请求资源:
location /media/ { alias /usr/share/nginx/media/; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; }
- 重启服务并清理缓存
- 重启宿主机Nginx:
sudo systemctl restart nginx - 重启Docker容器:
docker-compose restart(若使用docker-compose) - 清除浏览器缓存,强制刷新页面(Ctrl+Shift+R)
验证
打开浏览器开发者工具(F12),切换到「网络」标签,确认媒体资源的请求协议为HTTPS,同时检查控制台是否仍有Mixed Content警告。
内容的提问来源于stack exchange,提问作者mirodil
相关产品推荐
相关产品推荐

