【问题标题】:ngnix redirect every subdomain except www to a specific pathnginx 将除 www 之外的每个子域重定向到特定路径
【发布时间】:2016-05-27 18:19:42
【问题描述】:

我有一个问题,我想将除 www 之外的所有子域重写到特定文件夹。 问题是这是在一个 docker 容器内运行的,它有一个外部卷和不同主机的动态主机名。所以我必须使用 $hostname。 只要您使用 $hostname,它就会受到与正则表达式规则相同的威胁。因此,为 www 创建一条规则不起作用,因为它对 www.$hostname 和 *.$hostname 或那里的正则表达式具有相同的威胁。

我尝试了多种方法,直接从 server_name 的变量中提取它根本不起作用,我现在处于一个带有负前瞻的条件正则表达式,它在任何正则表达式测试器上都可以正常工作,但在 ngnix 中却不行 2016/02/16 12:28:14 [emerg] 1#0: /etc/nginx/sites-enabled/default:10 中的无效条件“(?!www.)(\w”

有人有什么想法吗?

server {
    listen 443 ssl;
    listen 80;
    server_name *.$hostname;
    error_log /var/log/nginx/rewrite.log debug;
    root /src/webapp/dist;
    ssl_certificate /etc/nginx/ssl/server-cert.pem;
    ssl_certificate_key /etc/nginx/ssl/server-key.pem;

    if ($http_host ~ ((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.$hostname)) {
        set $subdomain $1;
        return 301 $scheme://www.$hostname/#/$subdomain/media/portfolio/1;
        break;
    }

}

也在块下面进行了测试,同样的结果根本没有重定向工作,它再次位于带有 ngninx 1.4.6-1ubuntu3.4 的 docker 容器内:

server {
    listen 80;
    listen 443 ssl;
    server_name www.$hostname;
    root /src/webapp/dist;

    ssl_certificate /etc/nginx/ssl/server-cert.pem;
    ssl_certificate_key /etc/nginx/ssl/server-key.pem;

}

server {
    listen 80;
    listen 443 ssl;
    server_name *.$hostname;

    ssl_certificate /etc/nginx/ssl/server-cert.pem;
    ssl_certificate_key /etc/nginx/ssl/server-key.pem;

   return 301 $scheme://www.$hostname/#/media/portfolio/1;
}

【问题讨论】:

    标签: regex redirect nginx


    【解决方案1】:

    您可以使用两个服务器块来处理它。第一个服务器块将处理www.$hostname,第二个将适用于所有其他情况。

    这是一个例子:

    server {
            listen 80;
            listen 443 ssl;
            server_name www.$hostname;
    
            ssl_certificate /etc/nginx/ssl/server-cert.pem;
            ssl_certificate_key /etc/nginx/ssl/server-key.pem;
            # Do whatever you want here
    }
    
    server {
            listen 80;
            listen 443 ssl;
            server_name *.$hostname;
    
            ssl_certificate /etc/nginx/ssl/server-cert.pem;
            ssl_certificate_key /etc/nginx/ssl/server-key.pem;
            # Do whatever you want here
    }
    

    如果您一直在考虑一些条件 if 语句 - 算了吧。这是个坏主意。 Nginx 支持ifs,但它们仅用于非常极端的情况,并且由于它们不像在普通编程语言中那样工作,因此非常不鼓励使用。

    【讨论】:

    • 由于 nginx 的一些奇怪行为,这是我所说的我已经尝试过的。它不起作用,因为它被忽略了
    • @Mario 请用您的确切代码更新您的问题,我确实测试了我发布的代码并且它确实有效。
    • 粘贴在上面,还是不行,没有使用其他配置,但是我发现不能使用正则表达式中的变量
    【解决方案2】:
    server {
        listen 443 ssl;
        listen 80;
        server_name *.$hostname;
        error_log /var/log/nginx/rewrite.log debug;
        root /src/webapp/dist;
        ssl_certificate /etc/nginx/ssl/server-cert.pem;
        ssl_certificate_key /etc/nginx/ssl/server-key.pem;
    
        if ($host ~* "((?:\w+(?:-\w+)*\.)*)((?!www\.)\w{3,}(?:-\w+)*)(\..*\.muc\.pom)") {
            set $subdomain $2;
            return 301 $scheme://www.$hostname/#/$subdomain/media/portfolio/1/about;
            break;
        }
    
    }
    

    Ngninx 不知何故无法在正则表达式中使用变量,所以我必须稍微解决一下 dns 结尾,对于生产使用,应该也有更好的解决方案,但是 hte 正则表达式是匹配和重写的。

    我知道 If 不好,如果有人可以为 docker 想出另一个解决方案,请随时分享

    【讨论】:

      猜你喜欢
      • 2021-11-03
      • 2020-11-09
      • 2022-01-11
      • 1970-01-01
      • 2013-10-28
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多