You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF接口返回HTTP文件链接引发HTTPS混合内容错误的解决方案咨询

DRF API返回HTTP文件链接导致HTTPS页面混合内容错误

已使用DRF搭建API应用,站点已安装SSL证书,但前端HTTPS页面(https://www.example.com)加载文件时出现错误:页面加载了不安全的HTTP资源(http://api.example.com/……)。返回的JSON示例中,媒体文件链接均以HTTP开头:

{
  "id": 50,
  "name": "Образец заполнения книги учета доходов",
  "category": "Бухгалтерия и налоги",
  "count_download": 0,
  "type_doc": "xls",
  "screenshot": "http://api.example.com/media/screenshot/%.png",
  "add_time": "2023-03-27",
  "pdffile": "http://api.example.com/media/pdf_docs/%.pdf"
}

环境使用容器化Nginx,配置如下:

server {
    server_name api.example.com;
    listen 80;
    root /var/html/;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name api.example.com;
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    root /var/html/;
    server_tokens off;
    client_max_body_size 10m;

   location ~ /.well-known/acme-challenge/ {
       root /var/www/certbot;
   }

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_pass http://backend:8000;
    }

    location /media/ {
        autoindex on;
    }

    location /docs/ {
        root /usr/share/nginx/html;
        try_files $uri $uri/redoc.html;
    }

    location /static/rest_framework/ {
        autoindex on;
    }

    location /static/admin/ {
         autoindex on;
    }

    location /admin/ {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_pass http://backend:8000/admin/;
    }
}

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/html/;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    server_name example.com www.example.com;
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    root /var/html/;

    location ~ /.well-known/acme-challenge/ {
       root /var/www/certbot;
    }

    location / {
        root /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri /index.html;
      }
}

解决方法

1. 配置Django识别HTTPS代理

Django默认无法感知反向代理后的HTTPS请求,需在settings.py中添加以下配置:

# 信任Nginx传递的HTTPS协议头
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# 允许的主机列表(根据实际域名调整)
ALLOWED_HOSTS = ['api.example.com', 'example.com', 'www.example.com']
# 使用代理传递的主机和端口信息
USE_X_FORWARDED_HOST = True
USE_X_FORWARDED_PORT = True

配置后,Django会基于代理头生成HTTPS格式的媒体文件链接。

2. 完善Nginx代理头配置

在api.example.com的443 server块中,为代理请求添加X-Forwarded-Proto头,将当前请求的协议(HTTPS)传递给后端Django:
修改location /和location /admin/部分:

location / {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    # 添加协议头
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://backend:8000;
}

location /admin/ {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    # 添加协议头
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://backend:8000/admin/;
}

3. 强制媒体URL使用HTTPS(备选方案)

如果上述配置不生效,可直接在settings.py中硬编码媒体URL的HTTPS前缀:

MEDIA_URL = 'https://api.example.com/media/'

注意:此方法适合域名固定的场景,域名变动时需同步修改。

4. 检查Nginx媒体文件服务配置

当前Nginx的location /media/仅开启了autoindex,需确保媒体文件能被正确访问:

  • 如果媒体文件由Django后端管理,将location /media/改为代理到后端:
location /media/ {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://backend:8000/media/;
}
  • 如果媒体文件直接挂载在Nginx容器中,指定文件路径:
location /media/ {
    root /path/to/your/media/directory;
    autoindex on;
}

内容的提问来源于stack exchange,提问作者Саша Асеев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:29:56