使用重定向循环Apache的mod_rewrite(干净的URL) [英] Redirect loop using Apache mod_rewrite (clean URLs)

查看:251
本文介绍了使用重定向循环Apache的mod_rewrite(干净的URL)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的情况非常相似,一个在这个问题(事实上,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] 标记,所以不应该有任何处理或重定向之后发生的事情,对吧?

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 matching RewriteRule.

一直以来,它会在每个目录的基础上匹配的,一旦你把以下内容:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆