使用重定向循环Apache的mod_rewrite(干净的URL) [英] Redirect loop using Apache mod_rewrite (clean URLs)
问题描述
我的情况非常相似,一个在这个问题(事实上,code是非常相似)。我一直在试图创建一个的.htaccess
文件中使用的URL没有文件扩展名,使如 https://example.com/file
找到 file.html
在相应的目录,而且还 https://example.com/file.html
重定向(使用HTTP重定向)为 https://example.com/file
所以只有一个规范的网址。用下面的的.htaccess
:
My situation is very similar to the one in this question (in fact, the code is very similar). I've been trying to create a .htaccess
file to use URLs without file extensions so that e.g. https://example.com/file
finds file.html
in the appropriate directory, but also that https://example.com/file.html
redirects (using a HTTP redirect) to https://example.com/file
so there is only one canonical URL. With the following .htaccess
:
Options +MultiViews
RewriteEngine On
# Redirect <...>.php, <...>.html to <...> (without file extension)
RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]
我已经运行到一个重定向循环正如上面提到的问题。 (在我的情况,找到相应的文件是由多视图
实现,而不是一个单独的重写规则
)
I've been running into a redirect loop just as in the question mentioned above. (In my case, finding the corresponding file is achieved by MultiViews
instead of a separate RewriteRule
.)
然而,随着从这个答案采用的解决方案:
However, with a solution adopted from this answer:
Options +MultiViews
RewriteEngine On
# Redirect <...>.php, <...>.html to <...> (without file extension)
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.+)\.(php|html)
RewriteRule ^ %1 [L,R]
没有重定向循环。我很想找出差别从何而来。是不是这两个文件功能上等同?为什么在使用正常重写规则
创建了一个循环,在使用%{THE_REQUEST}
不?
there is no redirect loop. I’d be interested to find out where the difference comes from. Aren’t both files functionally equivalent? How come that using a "normal" RewriteRule
creates a loop, while using %{THE_REQUEST}
doesn’t?
请注意,我的不可以寻找一种方式来获得干净的URL(我可以用我的文件或第二个版本的答案上面链接的问题,它看起来在%{ENV:REDIRECT_STATUS}
),但在原因为什么这两种方法工作/不工作,所以这不是作为一个同样的问题上面链接。
Note that I’m not looking for a way to get clean URLs (I could just use the second version of my file or the answer to the question linked above, which looks at %{ENV:REDIRECT_STATUS}
), but for the reason why these two approaches work/don’t work, so this is not the same question as the one linked above.
注意:我看到只用了mod_rewrite同样的问题(没有多视图
),所以它似乎并不因多视图
的执行和mod_rewrite的顺序:
Note: I'm seeing the same problem using only mod_rewrite (without MultiViews
), so it doesn't seem to be due to the order of execution of MultiViews
and mod_rewrite:
Options -MultiViews
RewriteEngine On
## Redirect <...>.php, <...>.html to <...> (without file extension)
# This works...
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.+)\.(php|html)
RewriteRule ^ %1 [L,R]
# But this doesn’t!
#RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]
# Find file with file extension .php or .html on the filesystem for a URL
# without file extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^ %{REQUEST_FILENAME}.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^ %{REQUEST_FILENAME}.html [L]
在哪里不同?我希望这两种方法来工作,因为内部重写到一个文件是在的.htaccess
与 [L] $的尽头C $ C>标记,所以不应该有任何处理或重定向之后发生的事情,对吧?
Where’s the difference? I would expect both approaches to work because the internal rewrite to a file is at the very end of the .htaccess
with an [L]
flag, so there shouldn't be any processing or redirecting happening afterwards, right?
推荐答案
如果你看一下 重写规则
指令的文档,你会发现以下内容:
If you look at RewriteRule
directive's documentation, you'll notice the following:
在第一个重写规则
,这是对(%-de codeD)匹配
请求的URL的路径,或在每个目录上下文(见下文),则
URL路径相对于每个目录上下文。随后的模式
正在对最后匹配的输出匹配重写规则
。
On the first
RewriteRule
, it is matched against the (%-decoded) URL-path of the request, or, in per-directory context (see below), the URL path relative to that per-directory context. Subsequent patterns are matched against the output of the last matchingRewriteRule
.
一直以来,它会在每个目录的基础上匹配的,一旦你把以下内容:
Since, it will be matched on a per directory basis, once you put the following:
RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]
在 REQUEST_URI
变量的变化,而mod-rewrite再次解析URI。这导致多视图
重写URL来匹配此重定向的URL,造成一个循环(每次改写URI的变化)正确的文件。
the REQUEST_URI
variable changes, and mod-rewrite parses the URI again. This leads to MultiViews
rewriting the URL to the proper file matching this redirected URL and causing a loop (URI changes on every rewrite).
现在,当你把 THE_REQUEST
变量来匹配,则URI可以改变内部重写,而是由服务器接收到的实际要求永远不会改变。
Now, when you put THE_REQUEST
variable to match against, the URI may change on internal rewrites, but the actual request as received by the server would never change unless a redirect is performed.
这篇关于使用重定向循环Apache的mod_rewrite(干净的URL)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!