php Nginx 将所有请求从子目录重定向到另一个子目录根目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22224441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:44:45  来源:igfitidea点击:

Nginx redirect all requests from subdirectory to another subdirectory root

phpredirectnginx

提问by user1214769

I'm quite new to Nginx so please bear with me.

我对 Nginx 很陌生,所以请耐心等待。

I'm trying to redirect all requests from one subdirectory (store) to the root of another subdirectory (trade). See my progress below. The site in the target subdirectory (trade) is a magento site so that is what most of the current rules are for.

我试图将所有请求从一个子目录(商店)重定向到另一个子目录(贸易)的根目录。在下面查看我的进度。目标子目录 (trade) 中的站点是一个 magento 站点,因此大多数当前规则都适用于该站点。

server {
    server_name example.com *.example.com;
    root /usr/share/nginx/html/example.com/public_html;
    index index.php index.html index.htm;

    access_log /var/log/nginx/example.access.log;
    error_log /var/log/nginx/example.error.log;

    location / {
            try_files $uri $uri/ /index.html;
    }

    location /trade/ {
            index index.html index.php;
            try_files $uri $uri/ @handler;
            expires 30d;
    }

    location ~ /store {
            rewrite /trade permanent;
    }

    location ~ ^/trade/(app|includes|lib|media/downloadable|pkginfo|report/config.xml|var)/ { internal; }
    location /trade/var/export/ { internal; }
    location /. { return 404; }
    location @handler { rewrite / /trade/index.php; }

    error_page 404 /404.html;

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
          root /usr/share/nginx/html;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
            try_files $uri =404;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;

    }


}

The section I am using to redirect is the following:

我用来重定向的部分如下:

location ~ /store {
        rewrite /trade permanent;
}

This works for example.com/store but not example/store/index.php or any other uri with args. I have a feeling that the php file section at the bottom is overriding the processing. That is why I have put the ~ in front of the store location as the documentation herestates this will be processed first. Does the processing stop or continue on?

这适用于 example.com/store 但不适用于 example/store/index.php 或任何其他带有 args 的 uri。我有一种感觉,底部的 php 文件部分正在覆盖处理。这就是我将 ~ 放在商店位置前面的原因,因为此处的文档说明这将首先处理。处理是停止还是继续?

I have read about nesting a php rule but I have tried this to no avail.

我已经阅读了关于嵌套 php 规则的内容,但我已经尝试过无济于事。

I would greatly appreciate any help.

我将不胜感激任何帮助。

回答by Mohammad AbuShady

ok try something like this

好的,试试这样的

location ^~ /store(.*) {
  return 301 $scheme://$http_host/trade$is_args$query_string;
}

Trying to avoid hardcoded stuff as much as possible and using return because it's prefered over permanent rewrites

尽量避免硬编码的东西并使用 return 因为它比永久重写更受欢迎

回答by user1214769

Ok,

好的,

Coming back to this I can see the issue.

回到这个我可以看到这个问题。

In Nginx when you prepend a location directive with ~ this means that you want to process regular expressions in your directive (case sensitive, ~* for case insensitive). I believe that all regex directives will process before any others but I stand to be corrected.

在 Nginx 中,当你在 location 指令前加上 ~ 这意味着你想在你的指令中处理正则表达式(区分大小写,~* 表示不区分大小写)。我相信所有正则表达式指令都会在任何其他指令之前处理,但我会得到纠正。

So when I am using:

所以当我使用:

location ~/store {
       rewrite /trade permanent;
}

There is no regex there. Its is simply matching /store and redirecting to trade.

那里没有正则表达式。它只是匹配 /store 并重定向到交易。

After some investigation (and polishing up on my regex, which is rubbish), I came back to it and have come up with a working solution.

经过一些调查(并改进了我的正则表达式,这是垃圾),我回到了它并提出了一个可行的解决方案。

location ~ ^/store/(.*) {
            rewrite ^/store(.*) /trade permanent;
    }

Here I am asking the directive to process the regex by entering ~ then match any url with /store/ in it.

在这里,我要求指令通过输入 ~ 然后将任何 url 与 /store/ 匹配来处理正则表达式。

Then, according to the docs, the rewrite syntax is:

然后,根据文档,重写语法是:

rewrite regex replacement [ flag ]

重写正则表达式替换 [ flag ]

so I am matching all urls with store in it and permanently redirecting them to the new subfolder.

所以我将所有网址与其中的商店进行匹配,并将它们永久重定向到新的子文件夹。

Pretty easy really, embarrassingly so actually but hey, every day is a school day. I'm open to correction on all of this and hope it helps someone.

真的很容易,实际上很尴尬,但是嘿,每天都是上学日。我愿意纠正所有这些,希望它对某人有所帮助。

回答by cnst

You need to ensure that your location ~ \.php$handler does not take any URLs below the old folder. Indeed, precedence rules are clearly documented within http://nginx.org/r/location, and you can either use regular expressions, or, better yet, use prefix-based matching with the ^~modifier to instruct that the search must stop without trying to see if that regex-based \.php$locationwould match:

您需要确保您的location ~ \.php$处理程序不使用旧文件夹下的任何 URL。事实上,优先规则在http://nginx.org/r/location 中有明确记录,您可以使用正则表达式,或者更好的是,使用基于前缀的匹配与^~修饰符来指示搜索必须停止而不尝试查看基于正则表达式的内容\.php$location是否匹配:

    location ^~ /old/long/path/ { # will match /old/long/path/index.php, too
        rewrite  ^/old/long/path/(.*)$  /new/  permanent;
    }

The above snippet is likely the most efficient way of doing this, but here is another way of doing the same:

上面的代码片段可能是最有效的方法,但这里有另一种方法:

    location ~ /old/long/path/(.*) {
        return  301  /new/$is_args$args;
    }

Why does one example has $is_args$argsand the other one doesn't? Good question! Note that locationdirective as well as the first parameter of the rewritedirective both operate based on the contents of the $urivariable, as opposed to $request_uri. Long story short, but $uridoes not contain $args, so, in both cases, $1will not contain any args; however, in the case of rewrite, the case is deemed so common that $argsare automatically added back by nginx, unless the new string ends with a ?character, see http://nginx.org/r/rewrite.

为什么一个例子有$is_args$args而另一个没有?好问题!请注意,location指令以及指令的第一个参数rewrite都基于$uri变量的内容进行操作,而不是$request_uri. 长话短说,但$uri不包含$args,因此,在这两种情况下,$1都不会包含任何args; 然而,在 的情况下rewrite,这种情况被认为是很常见的,$args由 nginx 自动添加回来,除非新字符串以?字符结尾,请参阅http://nginx.org/r/rewrite