仅在找不到文件时才重定向请求?

时间:2021-09-04 11:18:45

I'm hoping there is a way to do this with mod_rewrite and Apache, but maybe there is another way to consider too.

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

On my site, I have directories set up for re-skinned versions of the site for clients. If the web root is /home/blah/www, a client directory would be /home/blah/www/clients/abc. When you access the client directory via a web browser, I want it to use any requested files in the client directory if they exist. Otherwise, I want it to use the file in the web root.

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

For example, let's say the client does not need their own index.html. Therefore, some code would determine that there is no index.html in /home/blah/www/clients/abc and will instead use the one in /home/blah/www. Keep in mind that I don't want to redirect the client to the web root at any time, I just want to use the web root's file with that name if the client directory has not specified its own copy. The web browser should still point to /clients/abc whether the file exists there or in the root. Likewise, if there is a request for news.html in the client directory and it does exist there, then just serve that file instead of the web root's news.html. The user's experience should be seamless.

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

I need this to work for requests on any filename. If I need to, for example, add a new line to .htaccess for every file I might want to redirect, it rather defeats the purpose as there is too much maintenance needed, and a good chance for errors given the large number of files.

我需要这个来处理任何文件名的请求。例如,如果我需要为.htaccess为我可能想要重定向的每个文件添加一个新行,它就会失去目的,因为需要太多的维护,并且在给定大量文件的情况下很有可能出错。

In your examples, please indicate whether your code goes in the .htaccess file in the client directory, or the web root. Web root is preferred.

在您的示例中,请指明您的代码是否位于客户端目录中的.htaccess文件或Web根目录中。 Web root是首选。

6 个解决方案

#1


25  

# 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] 

From Rewrite if files do not exist

如果文件不存在,则从“重写”

#2


9  

How about this?

这个怎么样?

# 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]

#3


4  

I seemed to have at least one problem with each of the examples above. %{DOCUMENT_ROOT} seemed to do the wrong thing in certain places, and some / characters seem to be missing. Here is my solution, which goes in the .htaccess in the web root.

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

Instead of using two rules (one for the case where the file under clients/ is found, and one for not found), all I need to check is if the requested file (or directory) does NOT exist. Because if it exists, no change is needed, it can just use the file provided in the client dir. Here's the code I settled on:

而不是使用两个规则(一个用于找到clients /下的文件,一个用于未找到的文件),我需要检查的是所请求的文件(或目录)是否不存在。因为如果它存在,则不需要进行任何更改,它只能使用客户机目录中提供的文件。这是我确定的代码:

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

Thanks for your help!

谢谢你的帮助!

#4


3  

RewriteCond %{REQUEST_FILENAME} !-f

#5


0  

Try this:

尝试这个:

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

#6


0  

I think you want something along these lines:

我想你想要这些东西:

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

#1


25  

# 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] 

From Rewrite if files do not exist

如果文件不存在,则从“重写”

#2


9  

How about this?

这个怎么样?

# 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]

#3


4  

I seemed to have at least one problem with each of the examples above. %{DOCUMENT_ROOT} seemed to do the wrong thing in certain places, and some / characters seem to be missing. Here is my solution, which goes in the .htaccess in the web root.

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

Instead of using two rules (one for the case where the file under clients/ is found, and one for not found), all I need to check is if the requested file (or directory) does NOT exist. Because if it exists, no change is needed, it can just use the file provided in the client dir. Here's the code I settled on:

而不是使用两个规则(一个用于找到clients /下的文件,一个用于未找到的文件),我需要检查的是所请求的文件(或目录)是否不存在。因为如果它存在,则不需要进行任何更改,它只能使用客户机目录中提供的文件。这是我确定的代码:

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

Thanks for your help!

谢谢你的帮助!

#4


3  

RewriteCond %{REQUEST_FILENAME} !-f

#5


0  

Try this:

尝试这个:

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

#6


0  

I think you want something along these lines:

我想你想要这些东西:

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