ngnix将除www以外的每个子域重定向到特定路径

时间:2016-02-16 12:49:19

标签: regex redirect nginx

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

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

有人有任何想法吗?

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;
}

2 个答案:

答案 0 :(得分:0)

您可以使用两个服务器块来处理它。第一个服务器块将处理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支持if,但它们只适用于非常极端的情况,因为它们不像普通的编程语言那样工作,所以它们的使用非常沮丧。

答案 1 :(得分:0)

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结尾处理一下,对于生产使用应该也有更好的解决方案,但是正则表达式是匹配和重写。

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

相关问题