【问题标题】:Redirect requests only if the file is not found?仅在找不到文件时才重定向请求?
【发布时间】:2010-10-10 08:22:13
【问题描述】:

我希望有一种方法可以使用 mod_rewrite 和 Apache 来做到这一点,但也许还有另一种方法可以考虑。

在我的网站上,我为客户的网站重新皮肤版本设置了目录。如果 Web 根目录是 /home/blah/www,则客户端目录将是 /home/blah/www/clients/abc。当您通过 Web 浏览器访问客户端目录时,我希望它使用客户端目录中的任何请求文件(如果存在)。否则,我希望它使用 web 根目录中的文件。

例如,假设客户端不需要自己的index.html。因此,某些代码会确定/home/blah/www/clients/abc 中没有index.html,而是使用/home/blah/www 中的那个。请记住,我不想在任何时候将客户端重定向到 Web 根目录,如果客户端目录没有指定自己的副本,我只想使用具有该名称的 Web 根目录的文件。 Web 浏览器仍应指向/clients/abc 文件是否存在于那里或根目录中。同样,如果在客户端目录中有对news.html 的请求并且它确实 存在,那么只需提供该文件而不是Web 根目录的news.html。用户体验应该是无缝的。

我需要它来处理任何文件名的请求。例如,如果我需要为我可能想要重定向的每个文件添加一个新行到.htaccess,这反而会破坏目的,因为需要太多维护,并且考虑到大量文件很有可能出错.

在您的示例中,请说明您的代码是在客户端目录中的 .htaccess 文件中,还是在 Web 根目录中。首选 Web 根目录。

【问题讨论】:

    标签: apache .htaccess mod-rewrite


    【解决方案1】:
    # If requested resource exists as a file or directory, skip next two rules
    RewriteCond %{DOCUMENT_ROOT}/$1 -f [OR]
    RewriteCond %{DOCUMENT_ROOT}/$1 -d
    RewriteRule (.*) - [S=2]
    #
    # Requested resource does not exist, do rewrite if it exists in /archive
    RewriteCond %{DOCUMENT_ROOT}/archive/$1 -f [OR]
    RewriteCond %{DOCUMENT_ROOT}/archive/$1 -d
    RewriteRule (.*) /archive/$1 [L]
    #
    # Else rewrite requests for non-existent resources to /index.php
    RewriteRule (.*) /index.php?q=$1 [L] 
    

    来自Rewrite if files do not exist

    【讨论】:

      【解决方案2】:

      这个怎么样?

      # If requested resource exists as a file or directory go to it
      RewriteCond %{REQUEST_FILENAME} -f [OR]
      RewriteCond %{REQUEST_FILENAME} -d
      RewriteRule (.*) - [L]
      
      # Else rewrite requests for non-existent resources to /index.php
      RewriteRule (.*) /index.php?q=$1 [L]
      

      【讨论】:

      • else 部分是我很久不知道的东西......谢谢。
      【解决方案3】:

      我似乎对上面的每个示例都至少有一个问题。 %{DOCUMENT_ROOT} 似乎在某些地方做错了事,一些/ 字符似乎丢失了。这是我的解决方案,位于 web 根目录的 .htaccess 中。

      我不需要使用两条规则(一条用于找到 clients/ 下的文件,另一条用于未找到),我只需要检查请求的文件(或目录)是否不存在。因为如果存在,则无需更改,只需使用客户端目录中提供的文件即可。这是我确定的代码:

      RewriteEngine on
      RewriteCond %{DOCUMENT_ROOT}/clients/$1/$2 !-f
      RewriteCond %{DOCUMENT_ROOT}/clients/$1/$2 !-d
      RewriteRule ^clients/([^/]+)/(.*)$ $2 [L]
      

      感谢您的帮助!

      【讨论】:

        【解决方案4】:
        RewriteCond %{REQUEST_FILENAME} !-f
        

        【讨论】:

        • 似乎太短了,无法做我想做的事。你能稍微解释一下逻辑吗?谢谢!
        【解决方案5】:

        试试这个:

        RewriteEngine on
        RewriteRule ^clients/abc/ - [L]
        RewriteCond %{DOCUMENT_ROOT}clients/abc/$0 -f
        RewriteRule .* clients/abc/$0 [L]
        

        【讨论】:

        • 这是否适用于网络根目录中的 .htaccess?
        • 是的,它适用于文档根目录中的 .htaccess 文件。
        【解决方案6】:

        我认为你想要一些类似的东西:

        RewriteEngine on
        RewriteCond %{DOCUMENT_ROOT}clients/$1/$2 -f
        RewriteRule ^clients/([^/]+)/(.*)$ %{DOCUMENT_ROOT}clients/$1/$2 [L]
        RewriteRule ^clients/([^/]+)/(.*)$ %{DOCUMENT_ROOT}$2 [L]
        

        【讨论】:

        • 好点。但在 .htaccess 文件中,模式不能以斜杠开头。如果使用 DOCUMENT_ROOT 变量会更方便。
        • 您能否说明应该如何使用 DOCUMENT_ROOT 进行更新?它不能按原样工作。
        • 在 RewriteCond “/home/blah/www/” 中替换为 “%{DOCUMENT_ROOT}” 并在替换中将其删除。还要删除正则表达式模式中的前导“/”。那么它应该可以工作了。
        • 我已根据您的 cmets 进行了更新,Gumbo,谢谢。我没有考虑 .htaccess
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-08
        • 2017-04-17
        • 2012-06-19
        • 2019-12-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多