使用多个重写规则 .htaccess

使用多个重写规则 .htaccess

我有一个基于搜索页面的网站,它显示一个列表,接下来是项目的详细信息页面。

若访问者使用rootdomain.com/searchterm,应重定向至rootdomain.com/index.php?keyword=searchterm

我现在正在处理详细信息rootdomain.com/detail/productname,应重定向到rootdomain.com/detail.php?name=productname

但我失败了……

我不断被重定向到 index.php,其中 $1 为“detail/productname”

这是我.htacces迄今为止的情况:

RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/detail/(.*)$  detail.php?name=$1 [L,QSA] -> L here doesn't work either. 
RewriteRule ^(.*)$ index.php?keyword=$1 [L,QSA]

更新

好的,现在我已经很接近了

问题是重写条件仅对下一个规则有效,所以我必须重复这一点,显然,我还在第一个条件中添加了忽略detail.php,因为我对detail的重定向再次重定向到索引。现在由于某种原因,我的-f条件似乎对detail不起作用/我的所有css和图像都不起作用。排除它们的最佳方法是什么

RewriteEngine on
RewriteCond $1 !^(index\.php|detail\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^detail/(.*)$  detail.php?name=$1 [L,QSA] 

RewriteCond $1 !^(index\.php|detail\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?keyword=$1 [L,QSA]

更新 2

所以我让它工作了。但我猜这不是最短的方法。所以如果有人感兴趣,可以把它写得更短一些。

RewriteEngine on
RewriteCond $1 !^(index\.php|detail\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^detail/(images|css|js)/(.*)$  $1/$2 [L,QSA] 

RewriteCond $1 !^(index\.php|detail\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^detail/(.*)$  detail.php?name=$1 [L,QSA] 

RewriteCond $1 !^(index\.php|detail\.php|resources|robots\.txt|\.png)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?keyword=$1 [L,QSA]

答案1

您需要将L(“last”)标志添加到第一个RewriteRule

RewriteRule ^/detail/(.*)$  detail.php?name=$2 [L,QSA]

根据文档,此标志将:

在此停止重写过程,不再应用任何重写规则。这对应于 Perl 中的 last 命令或 C 中的 break 命令。使用此标志可防止当前重写的 URL 按照以下规则进一步重写。

如果没有它,Apache 会在匹配第一条重写规则后继续应用第二条重写规则。由于第二条规则会影响所有内容,因此它会覆盖第一条规则。(另一种解决方案是编写模式,使没有两个 URL 匹配相同的模式,例如,将第二个模式更改为^[^/](.*)$。)

答案2

所以我让它工作了。但我猜这不是最短的方法。所以如果有人感兴趣,可以把它写得更短一些。

发生了什么,第一个版本,从detail/something重定向成功了,但随后被重定向到index.php?keyword=detail.php?name=something,所以我不得不在第一个条件行中排除detail.php。此外,rewriteCond对下一个规则有效,但不是对所有规则都有效。所以我不得不重复它们。

最后,为了使我的图像和 CSS 正常工作,我必须将它们重写为包含 images/css/js 的 3 个文件夹的基本 URL。

如果可以将其缩短或更充分,请随意这样做

RewriteEngine on
RewriteCond $1 !^(index\.php|detail\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^detail/(images|css|js)/(.*)$  $1/$2 [L,QSA] 

RewriteCond $1 !^(index\.php|detail\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^detail/(.*)$  detail.php?name=$1 [L,QSA] 

RewriteCond $1 !^(index\.php|detail\.php|resources|robots\.txt|\.png)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?keyword=$1 [L,QSA]

--edit 当使用详细信息/后面的 urlencoded 部分时,它似乎仍然不是万无一失的。。。

相关内容