如何防止mod_rewrite多次重写URL?

时间:2011-10-04 12:22:30

标签: apache mod-rewrite

我想使用mod_rewrite将一些人性友好的URL重写为名为php的文件夹中的任意文件(在web根目录中,因为mod_rewrite显然不会让你重写到网络外的文件根)。

/        --> /php/home.php
/about   --> /php/about_page.php
/contact --> /php/contact.php

以下是我的重写规则:

Options +FollowSymlinks
RewriteEngine On

RewriteRule ^$ php/home.php [L]
RewriteRule ^about$ php/about_page.php [L]
RewriteRule ^contact$ php/contact.php [L]

但是,我还想阻止用户直接访问此php目录中的文件。如果用户输入以/php开头的任何网址,我希望他们获得404页面。

我尝试在最后添加这个额外的规则:

RewriteRule ^php php/404.php [L]

...(其中404.php是一个输出404标题和“未找到”消息的文件。)

但是当我访问//about或/ contact时,我总是被重定向到404.似乎最终的RewriteRule甚至应用于内部重写的URL(因为它们现在都以/php开头。

我认为[L]标志(在前三个RewriteRules上)应该阻止进一步的规则被应用?难道我做错了什么? (或者有更聪明的方法来做我想做的事情吗?)

2 个答案:

答案 0 :(得分:0)

[L]标志只能在最后一条规则中使用,

L - 最后规则 - 停止重写过程,不再应用任何重写规则&因为你正面临着问题。

答案 1 :(得分:0)

我有类似的问题。我有一个用PHP编写的内容管理系统,它基于Model-View-Control范例。最基本的部分是mod_rewrite。我已成功阻止全局访问PHP文件。技巧名为THE_REQUEST

有什么问题?

重写模块会重写URI。如果URI与规则匹配,则将其重写,并在新的重写URI上应用其他规则。但!如果匹配的规则以[L]结尾,则引擎实际上不会终止,而是再次启动。然后,新URI与以[L]结尾的规则不再匹配,继续并匹配最后一个。结果?程序员明星在意外的404错误页面上说坏话。然而,计算机做什么,你说什么,不做什么,你想要什么。我在我的.htaccess文件中有这个:

RewriteEngine On
RewriteBase /
RewriteRule ^plugins/.* pluginLoader.php [L]

RewriteCond %{REQUEST_URI} \.php$
RewriteRule .* index.php [L]

那是错的。即使以plugins/开头的URI也会被重写为index.php

<强>解决方案

当且仅当原始 - 未重写 - URI与规则匹配时,您才需要应用规则。遗憾的是,mod_rewrite不提供包含原始URI的任何变量,但它提供了一些THE_REQUEST变量,其中包含第一行HTTP请求标头。这个变量是不变的。重写引擎工作时它不会改变。

...
RewriteCond %{THE_REQUEST} \s.*\.php\s
RewriteRule \.php$ index.php [L]

正则表达式不同。它不仅仅应用于URI,而是应用于标题的整个第一行,这意味着类似于GET /script.php HTTP/1.1。但关键规则是仅在用户直接明确请求某些PHP脚本时应用此时间。不使用重写的URI。

相关问题