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