【问题标题】:Remove all Subfolders Condition Rewrite .htaccess Apache 1.3.42删除所有子文件夹条件重写 .htaccess Apache 1.3.42
【发布时间】:2013-11-16 02:23:35
【问题描述】:

我对删除子文件夹进行了大量研究,但是无法创建一个 .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 规则应该无限期地保持这种模式,而无需我将子文件夹的名称添加到我的规则中,有点像通配符条件或包罗万象的场景。

但是,有一个条件,如果文件与我在上面的示例中说明的名称相同,则仅删除子文件夹。

我使用的是 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 .htaccess mod-rewrite


    【解决方案1】:

    我这里没有设置来通过实际安装的 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 错误日志并阅读它给出的错误。 Here 证明它适用于 Apache 2.4.4 上的干净 .htaccess,虽然检查错误日志需要 1 分钟,但我需要几个小时才能阅读过去 3 年所有 Apache 版本的所有补丁说明。

    外部重定向,内部重写,防止死循环

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

    #The external redirect
    RewriteCond %{THE_REQUEST} ^(GET|POST)\ /(.*?)([^/]+)/(?=\3(/|\ ))
    RewriteRule ^(.*?)([^/]+)/(?=\2(/|$))([^/]+)/?$ /$1$4 [R,L]
    
    #The internal rewrite
    RewriteCond %{REQUEST_URI} !^/(.*?)([^/]+)/(?=\2(/|$))([^/]+)/?$
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*/|)([^/]+)/?$ /$1$2/$2 [L]
    

    你提到了DirectorySlash Off。请注意,在当前版本的 Apache 上,这只会应用于实际的外部请求。在进行内部重写时,您是安全的。在上面的两个示例中,在 Apache 2.4.4 中,即使我重定向到没有尾部斜杠的 url,Apache 仍然会在第二次重定向中附加斜杠。我不知道在 1.3 中是如何处理的。


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

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

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

    【讨论】:

    • @anubhava 实际上,为了更清楚,我希望 www.domain.com/dan/ 指向 www.domain.com/dan/dan 但我希望 www.domain.com/dan/dan 指向如果这有意义的话,看起来像 www.domain.com/dan。这是删除 Apache 1.3.42 的斜线的一种迂回方式,因为现代 DirectorySlash Off 使我的服务器崩溃。无论如何,我将你的代码粘贴到我的 .htaccess 文件中,它也让我崩溃了,所以没有骰子。
    • @RichardMorris 你知道,我有点生你的气了。你用很多花哨的词张贴了很多问题,表明你不知道你在说什么。这对我来说没问题。我回答了这个问题,因为答案不是基础知识。然而,如何将 A 外部重定向到 B 并在内部将 B 重写为 A 是基本知识,并且可以在互联网的每个角落找到。自己做一些研究。没有任何重写规则会crash apache(apache 服务停止)。您可能会遇到内部服务器错误。找出那是什么。
    • @RichardMorris 了解如何找出发生了什么错误。 Here 证明这条规则可以正常工作。我想,因为您使用的是古老的 Apache 版本,您不仅容易受到服务器上的各种攻击,而且可能缺少正则表达式引擎中的环视功能。我很乐意教东西,但如果我需要为你准备好一切以便你可以懒洋洋地复制/粘贴它(实际上没有从中学习),那么请转到其他网站。
    • @Sumurai8 你为什么感到恼火?到目前为止,我在这个网站上只发布了 4 个问题,我不知道有限制吗?花言巧语,请澄清一下?请解释为什么你认为我不知道我在说什么?我知道答案不是基本知识,因为如果是的话,我早就找到答案了。 “然而,如何将 A 外部重定向到 B 并在内部将 B 重写为 A 是基础知识,并且可以在互联网的每个角落找到。”显然,这不是基本知识,因为您甚至不知道自己的答案,因为您上面的答案失败了。
    • @Sumurai8 如果您完整阅读我的帖子,您会意识到我已经做了很多研究。内部错误是崩溃,如果您的意思是灾难性崩溃,则不是,不是。请停止对我使用这种居高临下的语气,您的辱骂行为是不受欢迎的。古老的阿帕奇,这里不需要和用户说话,请立即停止。我也很乐意教你。我很确定管理员希望我在他们的网络上点击他们的广告,而不是在其他网站上,所以无论如何谢谢,但不,谢谢。现在请清理你的语气。
    猜你喜欢
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 2015-06-28
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多