我在网站上使用以下代码,并且正在工作。

RewriteEngine On
RewriteBase /a/b/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/?$ index.php?slug=$1 [QSA,L]

我能够访问我的网站

https://www.example.com/a/b/testing

现在,我正在遇到301个重定向的问题。

我尝试了以下代码

Redirect 301 /oldurl /newurl

但是,在访问URL I时,AM略低于URL

https://www.example.com/a/b/newurl?slug=oldurl

我的预期输出是下面的URL。

https://www.example.com/a/b/newurl
分析解答

您应该避免在相同的上下文中混合Redirect (mod_alias)和RewriteRule (mod_rewrite)指令,以免得到这些意外的冲突。尽管在mod_alias之前处理了mod_rewrite,尽管Config和Redirect中的指令明显顺序在请求的URL-path上工作(不是重写的URL-path,而不是查询字符串)。

因此,请求/oldurl时发生了什么,您将Redirect 301 /oldurl /newurl与现有mod_rewrite重写一起使用是:

  1. mod_rewrite内部将请求重写为index.php?slug=oldurl
  2. Redirect创建了一个从/oldurl(最初要求URL-path)到/newurl的重定向
    • 查询字符串(如果有)附加到目标URL。现在是slug=oldurl,因为mod_rewrite对其进行了修改。
  3. 由此产生的URL为/newurl?slug=oldurl

(如上所述,这都是指令的顺序,因为它们来自两个不同的模块。)

解决方案

您还需要使用mod_rewrite进行重定向,这必须在现有重写之前进行(由于指令属于同一模块很重要)。例如:

RewriteEngine On
RewriteBase /a/b/

RewriteRule ^oldurl$ /newurl [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) index.php?slug=$1 [QSA,L]

保留了/oldurl上可能存在的任何查询字符串。例如。 /oldurl?foo=bar被重定向到/newurl?foo=bar(与Redirect一样)。如果您特别想删除任何查询字符串,则在重定向(first)规则上包含QSD标志(查询字符串丢弃)。

NB:我删除了正则尾部/?,因为它完全是多余的。由于您使代币可选,并且前面的量词是贪婪的,因此.*无论如何都会消耗可选的尾随斜线。如果打算从捕获的子图案中排除落后的斜线(如果有),则需要制作前面的量词non-greedy。例如。 (.*?)/?$(不需要start-of-string锚)。

(我假设您的.htaccess文件位于文档root中 - 看起来是,从您获得的错误重定向中,尽管/a/b/前缀有些混乱 - 见下文)


在旁边:

I have tried below code

Redirect 301 /oldurl /newurl

but while accessing the URL I am getting below URL

https://www.example.com/a/b/newurl?slug=oldurl

我本来希望这会导致/newurl?slug=oldurl,而不是/a/b/newurl?slug=oldurl