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

Nginx非www转www重定向对子目录失效,求问题原因分析

问题原因分析

你的问题出在HTTPS请求的处理逻辑上:第一个server块同时监听了example.com和www.example.com的443端口请求,所以当用户访问https://example.com/es/这类非www的HTTPS子目录时,请求直接匹配到这个server块里的location /规则,被代理到Gunicorn,完全没触发重定向逻辑。而第二个server块只负责处理80端口的HTTP请求,所以只有HTTP的首页和子目录会被重定向,HTTPS的非www请求根本没走到重定向步骤。

修正后的配置方案

你需要把HTTPS的server块拆分成两个:一个专门处理example.com的HTTPS请求并做重定向,另一个处理www.example.com的HTTPS请求并处理业务逻辑。修改后的完整配置如下:

# 处理非www的HTTPS请求,直接重定向到www版本
server {
    server_name example.com;
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.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

    # 所有请求都重定向到www.example.com,保留完整请求路径
    return 301 https://www.example.com$request_uri;
}

# 处理www的HTTPS请求,负责业务逻辑
server {
    server_name www.example.com;
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.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

    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }

    location /core/static {
        alias /home/andrea/agency/core/static/;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

# 处理HTTP请求,统一重定向到HTTPS的www版本
server {
    listen 80;
    server_name example.com www.example.com;

    if ($host = example.com) {
        return 301 https://www.example.com$request_uri;
    }

    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    }

    return 404; # managed by Certbot
}
关键改动说明
  • 拆分了HTTPS的server块:现在example.com的HTTPS请求会被单独捕获,直接返回301重定向,确保所有非www的HTTPS请求(包括子目录)都能跳转到对应的www路径。
  • 保留了$request_uri:这个变量确实会完整保留请求的路径和参数,所以重定向后example.com/es/会正确跳转到www.example.com/es/。
  • 原有的业务逻辑(静态文件、Gunicorn代理)只保留在www.example.com的server块中,避免冲突。

修改完成后,记得重启Nginx生效:

sudo systemctl restart nginx

内容的提问来源于stack exchange,提问作者Askew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:42:46