如何将mod_rewrite重定向到相对URL

时间:2011-10-14 11:40:45

标签: apache mod-rewrite redirect

我正在尝试为漂亮的URL实现基本的URL重定向,并且由于图像,CSS等也位于相同的路径中,我需要确保如果访问的URL没有尾部斜杠,则会添加自动。

如果我把绝对URL放在这样:

,这样可以正常工作
RewriteRule ^myParentDir/([A-Z0-9_-]+)$ http://www.mydomain.com/myParentDir/$1/ [R,nc,L]

但是如果我将其更改为相对URL,那么每次我在文件夹中移动东西时都不必更改它,这根本不起作用。

这些是我尝试过但都没有用,或者将我重定向到服务器的实际内部目录路径,如/ public_html / ...:

RewriteRule ^myParentDir/([A-Z0-9_-]+)$ ./myParentDir/$1/ [R,nc,L]

RewriteRule ^myParentDir/([A-Z0-9_-]+)$ myParentDir/$1/ [R,nc,L]

进行网址重定向的正确方法是什么,以便用户输入如下内容:

http://www.mydomain.com/somedir/myVirtualParentDir/myVirtualSubdir

他被重定向到(通过HTTP 301或302):

http://www.mydomain.com/somedir/myVirtualParentDir/myVirtualSubdir/

感谢。

编辑:添加更多细节,因为它似乎并不清楚。 假设我正在实现一个库,我希望使用mod_rewrite拥有漂亮的URL。 所以,我希望网址如下:

http://www.mydomain.com/somedir/galleries/cats

显示了猫的缩略图,而:

http://www.mydomain.com/somedir/galleries/cats/persian

显示所有猫的缩略图中的一个图像,名为波斯语。 所以实际上物理目录结构和重写如下:

http://www.domain.com/somedir/gallery.php?category=cats&image=persian

所以我想做的是在/ somedir中放一个.htaccess文件来捕获对/ gallery的所有请求,并根据它后面的虚拟子目录,在重写时使用它们作为占位符,并使用2个重写规则:

RewriteRule ^galleries/(A-Z0-9_-]+)/$ ./gallery.php?category=$1 [nc]
RewriteRule ^galleries/(A-Z0-9_-]+)/+([A-Z0-9_-]+)$  ./gallery.php?category=$1&image=$2 [nc]

现在的问题是,图库脚本实际上需要一些CSS,Javascript和图像,分别位于http://www.domain.com/somedir/csshttp://www.domain.com/somedir/jshttp://www.domain.com/somedir/images

我不想硬编码任何绝对URL,因此CSS,JS和Images将使用相对URL(./css,./ js,。/ images等)引用。所以我可以按如下方式重写URL:

RewriteRule ^galleries/[A-Z0-9_-]+/css/(.*)$ ./css/$1 [nc]

问题是,由于http://www.domain.com/somedir/galleries/cats是一个虚拟目录,以上只有在用户输入时才有效:

http://www.domain.com/somedir/gallaries/cats/

如果用户省略了尾部斜杠,mod_dir将不会添加它,因为实际上这个目录实际上并不存在。

如果我使用绝对URL进行重定向重写,它可以工作:

RewriteRule ^galleries/([A-Z0-9_-]+)$ http://www.mydomain.com/subdir/galleries/$1/ [R,nc,L]

但我不想让URL前缀硬编码,因为我希望能够在我想要的任何子目录中将它放在我想要的任何域上,所以我尝试了这个:

RewriteRule ^galleries/([A-Z0-9_-]+)$ galleries/$1/ [R,nc,L]

但它重定向到:

http://www.mydomain.com/home/myaccount/public_html/subdir/galleries/theRest

这显然不是我想要的。

编辑:进一步澄清

我正在寻找的解决方案是避免在.htaccess中对域名或文件夹路径进行硬编码。我正在寻找一个解决方案,如果我将.htaccess与其余的脚本和资源打包在一起,只要用户在其Web服务器上解压缩它,它就可以开箱即用。除了这个尾随斜线问题之外,所有这些都是这样的。

所以任何涉及以任何方式对.htaccess中的父目录或web服务器路径进行硬编码的解决方案都不是我想要的。

4 个答案:

答案 0 :(得分:4)

这是直接来自Apache Documentation的解决方案(在“Trailing Slash Problem”下):

RewriteCond    %{REQUEST_FILENAME}  -d
RewriteRule    ^(.+[^/])$           $1/  [R]

这是a solution测试REQUEST_URI的尾部斜杠,然后添加它:

RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.+) http://www.example.com/$1/ [R=301,L]

这里允许您免除某些REQUEST_URI模式的another solution

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !example.php
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://domain.com/$1/ [L,R=301]

希望这些帮助。 :)

答案 1 :(得分:2)

此规则应该向任何不是真实文件/目录的URL添加一个尾部斜杠(我相信,因为Apache通常会自动为现有目录重定向,所以你需要它。)

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+[^/])$ $1/ [L,R=301]

编辑:

为了防止Apache附加相对于文档根目录的路径,您必须使用RewriteBase。因此,例如,在要作为应用程序根目录的文件夹中,添加以下内容,这将覆盖物理路径:

RewriteBase /

答案 2 :(得分:1)

可能有效:

RewriteRule ^myParentDir/[A-Z0-9_-]+$ %{REQUEST_URI}/ [NS,L,R=301]

但是,我不确定你为什么认为你需要这个。只需使你的CSS / JS /图像文件重写规则看起来像这样:

RewriteRule ^galleries/([A-Za-z0-9_-]+/)*(css|js|images)/(.*)$ ./$2/$3
无论浏览器是请求/somedir/galleries/css/whatever.css还是/somedir/galleries/cats/css/whatever.css还是/somedir/galleries/cats/persian/calico/css/whatever.css

都可以正常运行。

聚苯乙烯。此规则的一个问题是它会阻止您使用任何名称“css”,“js”或“images”。您可能希望通过命名这些虚拟目录来修复此问题,例如“.css”,“。js”和“.images”,或者使用一些与有效库名称不冲突的其他命名方案。

答案 3 :(得分:0)

我不确定我是否完全理解你的问题。

由于mod_dir模块,大多数Apache安装都会自动完成尾部斜杠重定向(99%的可能性是你的mod_dir模块)。

您可能需要添加:

DirectorySlash On

但这是默认值。

因此。如果您访问foo/bar并且bar不是foo目录中的文件而是子目录,那么mod_dir会执行重定向到foo/bar/

我所知道的唯一可以解决这个问题的是Option Multiviews,它可能试图在目录中找到一个bar.php,bar.php,bar.a-mime-extension-knwon-by-apache 。所以你可以尝试添加:

Option -Multiviews

删除所有重写规则。如果你没有得到这个默认的Apache行为,你可能不得不看看mod-rewrite,但就像使用核弹杀死蜘蛛一样。使用核弹可能会非常敏感。

修改 对于使用mod-rewrite的尾随斜杠问题,您可以检查此documentation howto,说明这应该有效:

RewriteEngine  on
RewriteBase    /myParentDir/
RewriteCond    %{REQUEST_FILENAME}  -d
RewriteRule    ^(.+[^/])$           $1/  [R]