将 RewriteCond %{QUERY_STRING} 从 Apache2 移植到 nginx

将 RewriteCond %{QUERY_STRING} 从 Apache2 移植到 nginx

我制作了一个大型 PHP 网站的静态镜像,使用以下 Apache2 重写节将查询字符串放入文件系统路径中,以正确提供静态文件。旧动态 URLfoo/?bar映射到静态文件foo/index.html@barfoo/image.php?bar映射到foo/image.php@bar- 所有内容,无论它出现在何处(在原始网站中最多出现 5 次),都被/替换为。举个例子,我有像这样的 URL,我需要将其映射到像这样的文件。%2Fbarexample.com/foo/?bar=baz/quuxfoo/index.html@bar=baz%2Fquux

# turn off php
php_admin_value engine off

# enable rewrites
RewriteEngine on

# rewrite .../?... to .../index.html@... with s|/|%2F|g

RewriteCond %{QUERY_STRING} ^([^/]+)$
RewriteRule ^(.*)/$ %{DOCUMENT_ROOT}/$1/index.html@%1 [L,T=text/html]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)$
RewriteRule ^(.*)/$ %{DOCUMENT_ROOT}/$1/index.html@%1\%2F%2 [L,T=text/html]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/$ %{DOCUMENT_ROOT}/$1/index.html@%1\%2F%2\%2F%3 [L,T=text/html]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/$ %{DOCUMENT_ROOT}/$1/index.html@%1\%2F%2\%2F%3\%2F%4 [L,T=text/html]

# rewrite .../image.php?... to .../image.php@... with s|/|%2F|g

RewriteCond %{QUERY_STRING} ^([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1 [L,T=image/jpeg]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1\%2F%2 [L,T=image/jpeg]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1\%2F%2\%2F%3 [L,T=image/jpeg]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1\%2F%2\%2F%3\%2F%4 [L,T=image/jpeg]

RewriteCond %{QUERY_STRING} ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)$
RewriteRule ^(.*)/image.php$ %{DOCUMENT_ROOT}/$1/image.php@%1\%2F%2\%2F%3\%2F%4\%2F%5 [L,T=image/jpeg]

上面的 Apache2 配置运行良好,但我们正在迁移到 nginx,我在为这个用例配置它时遇到了麻烦。我能想到几个解决方法,第一个是使用一个巨大的map指令列出网站上的所有 URL(由于大小而不可取),第二个是编写一个小型自定义 cgi 脚本(不可取,因为这旨在成为静态镜像)。

有没有优雅的解决方案?

(如果可以使事情变得更容易,那么重命名文件系统上的所有文件是一种选择,尽管我不知道如何做,但更改面向浏览器的 URL 是不可能的。)

答案1

前 4 个不是可以用这种方法吗?你必须按相反的顺序放置它们,这样全局位置才不会与其余位置匹配,然后才能达到目标。

location ~ ^/(?<path>.+)/(?<path2>.+)/(?<path3>.+)/(?<path4>.+)/.*$ {
    rewrite ^/(.*)/$ /$path/index.html@$query_string%2F$path%2F$path2%2F$path3%2F$path4 break;
}

location ~ ^/(?<path>.+)/(?<path2>.+)/(?<path3>.+)/.*$ {
    rewrite ^/(.*)/$ /$path/index.html@$query_string\%2F$path\%2F$path2\%2F$path3 break;
}

location ~ ^/(?<path>.+)/(?<path2>.+)/.*$ {
    rewrite ^/(.*)/$ /$path/index.html@$query_string\%2F$path\%2F$path2 break;
}

location ~ ^/(?<path>.+)/.*$ {
    rewrite ^/(.*)/$ /$path/index.html@$query_string\%2F$path break;
}

我尝试使用一个名为 foo 的目录,在其中放置了名为

  • index.html@bar%2Ffoo

  • index.html@bar%2Ffoo%2Ffoo2

当我访问http://myserver/foo/?bar当我访问时,我得到文件 index.html@bar%2Ffoohttp://myserver/foo/?bar我得到了文件index.html@bar%2Ffoo%2Ffoo2。

我让你适应image.php

相关内容