删除所有子文件夹条件重写。htaccess Apache 1.3.42

删除所有子文件夹条件重写。htaccess Apache 1.3.42,apache,.htaccess,mod-rewrite,Apache,.htaccess,Mod Rewrite,我已经做了很多关于删除子文件夹的研究,但是找不到创建.htaccess规则来删除我根目录中的所有子文件夹,示例如下: www.domain.com/dan/dan更改为www.domain.com/dan www.domain.com/pam/pam更改为www.domain.com/pam www.domain.com/jam/jam更改为www.domain.com/jam htaccess规则应该可以无限期地保持这种模式,而无需将子文件夹的名称添加到规则中,有点像通配符条件或catchal

我已经做了很多关于删除子文件夹的研究,但是找不到创建.htaccess规则来删除我根目录中的所有子文件夹,示例如下:

www.domain.com/dan/dan更改为www.domain.com/dan

www.domain.com/pam/pam更改为www.domain.com/pam

www.domain.com/jam/jam更改为www.domain.com/jam

htaccess规则应该可以无限期地保持这种模式,而无需将子文件夹的名称添加到规则中,有点像通配符条件或catchall场景

但是,有一个条件,只有当文件的名称与我在上面的示例中所示的名称相同时,才删除子文件夹

我在Apache 1.3.42上,因此需要一个不适用于较新版本的解决方案

在下面签出我的.htaccess文件,我对它做了很多SEO工作,如您所见:

AddType application/x-httpd-php .html

RewriteEngine On
RewriteBase /

#non www to www

RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

#removing trailing slash

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

#html

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.html [NC,L]

#index redirect

#directory remove index.html

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.html\ HTTP/
RewriteRule ^index\.html$ http://www.arkiq.com/ [R=301,L]

#directory remove index 

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\ HTTP/
RewriteRule ^index http://www.arkiq.com/ [R=301,L]

#sub-directory remove index.html

RewriteCond %{THE_REQUEST} /index\.html
RewriteRule ^(.*)/index\.html$ /$1 [R=301,L]

#sub-directory remove index

RewriteCond %{THE_REQUEST} /index
RewriteRule ^(.*)/index /$1 [R=301,L]

#remove .html

RewriteCond %{THE_REQUEST} \.html
RewriteRule ^(.*)\.html$ /$1 [R=301,L]

如果您知道如何使用一个规则将所有子文件夹转发到各自命名的文件,请告诉我,因为这将非常棒。

我在这里没有设置来用实际安装的apache测试这一规则,但我非常确信,您可以通过使用捕获组的正向前瞻来实现这一点

RewriteRule ^(.*?)([^/]+)/(?=\2(/|$))([^/]+)/?$ /$1$4 [R,L]
这有什么用<代码>^(.*)将匹配最后两个斜杠之前的所有内容。如果您转到
example.com/test/test
,它将完全不匹配<代码>([^/]+)将匹配我们要测试的第一件事情,并将其放入捕获组2中
(?=\2(/|$)
是正向前瞻。前瞻将“窥视”下一个字符,但不会消耗任何字符<代码>\2将替换为第二个捕获组,
(/|$)
将匹配斜杠或字符串结尾。最后一个
([^/]+)
将与第二个“东西”匹配,
/?
将确保url匹配,即使url末尾存在
/
。应用此规则后,应发生以下情况:

example.com/test/test --> example.com/test
example.com/test/test2 --> no rewrite, because '2' does not match '/' or the end of the string
example.com/test/test/ --> example.com/test
example.com/sub/test/test --> example.com/sub/test

调试此规则

如果您得到一个内部服务器错误,请转到apache错误日志并阅读它给出的错误。这证明它在Apache 2.4.4上的clean.htaccess上工作,虽然检查错误日志需要1分钟,但阅读过去3年所有Apache版本的所有补丁说明需要几个小时

外部重定向、内部重写、防止无限循环

假设上述规则适用于您的mod_rewrite/apache/regex版本,下面的构造将用于外部重定向您的请求,然后在内部将其重写回来。请注意,
/test/test
不会做任何明智的事情,除非您告诉apache如何执行这样的文件

您提到了目录斜杠。请注意,在当前版本的Apache上,这只会应用于实际的外部请求。在进行内部重写时,您是安全的。在上面的两个例子中,在Apache2.4.4中,即使我重定向到一个url而不带尾随斜杠,Apache仍然会在第二个重定向中附加斜杠。我不知道1.3是如何处理的


如果Apache1.3在它的正则表达式引擎中不支持反向引用或查找(我仍然无法测试),那么就没有真正的方法通过mod_rewrite测试url是否包含两个相同的段。您要么需要使用自定义路由器页面,要么写出每个url(这可能会导致性能问题,因为这可能会导致很多问题)。重写路由器页面的过程如下:

RewriteRule ^(.*)$ /myrouter.php?url=$1 [L]

此路由器页面使用您选择的语言,也可以使用自定义位置发送301或302头。它还需要处理与上述重写规则匹配的所有其他请求。

@anubhava实际上,为了更清楚,我希望www.domain.com/dan/指向www.domain.com/dan/dan,但如果这有意义的话,我希望www.domain.com/dan看起来像www.domain.com/dan。这是一种迂回的方式来删除Apache 1.3.42的斜杠,因为现代DirectorySlash-Off使我的服务器崩溃。不管怎么说,我把你的代码粘贴到了我的.htaccess文件中,它也使我崩溃了,所以没什么大不了的。@RichardMorris你知道,我对你有点恼火。你贴了很多问题,有很多花哨的词,表明你不知道自己在说什么。我没问题。我回答了这个问题,因为答案不是基础知识。然而,如何在外部将A重定向到B并在内部将B重写到A是基本知识,可以在互联网的每个角落找到。自己做一些调查。没有任何重写规则会使apache崩溃(apache服务停止)。您可能遇到内部服务器错误。找出那是什么。@RichardMorris找出如何找出发生了什么错误。这证明了这条规则很有效。我认为,由于您使用的是一个古老的Apache版本,因此您不仅容易受到服务器上各种各样的攻击,而且还可能缺少regex引擎中的lookaround功能。我很乐意教东西,但如果我需要为你准备一切,以便你可以懒洋洋地复制/粘贴它(而不是从中学习),那么请转到其他网站。@Sumurai8你为什么感到恼火?到目前为止,我在这个网站上只发布了4个问题,我不知道有限制吗?花言巧语,请澄清?请解释为什么你认为我不知道我在说什么?我知道答案不是基础知识,因为如果是的话,我已经找到了答案。“如何从外部将A重定向到B,并在内部将B重写到A,这是一门基础知识,可以在互联网的每个角落找到。”很明显,这不是基础知识,因为你自己都不知道答案,因为上面的答案失败了。@Sumurai8如果你完整阅读我的帖子,你会发现我已经做了很多研究。内部错误是崩溃,如果你指的是灾难性的崩溃,那么不是
RewriteRule ^(.*)$ /myrouter.php?url=$1 [L]