【发布时间】:2016-02-25 01:37:39
【问题描述】:
我的情况和this question中的情况很相似(其实代码很相似)。我一直在尝试创建一个 .htaccess 文件来使用没有文件扩展名的 URL,例如https://example.com/file 在适当的目录中找到 file.html,而且 https://example.com/file.html 重定向(使用 HTTP 重定向)到 https://example.com/file,因此只有一个规范 URL。用下面.htaccess:
Options +MultiViews
RewriteEngine On
# Redirect <...>.php, <...>.html to <...> (without file extension)
RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]
就像上面提到的问题一样,我遇到了重定向循环。 (在我的例子中,找到对应的文件是通过MultiViews而不是单独的RewriteRule来实现的。)
但是,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]
没有重定向循环。我很想知道差异来自哪里。两个文件在功能上不是等效的吗?为什么使用“普通”RewriteRule 会创建循环,而使用 %{THE_REQUEST} 不会?
请注意,我不是在寻找一种获取干净 URL 的方法(我可以使用我的文件的第二个版本或上面链接的问题的答案,它看起来像 %{ENV:REDIRECT_STATUS} ),但出于原因为什么这两种方法有效/无效,所以这与上面链接的问题不同。
注意:我只使用 mod_rewrite(没有 MultiViews)看到了同样的问题,所以这似乎不是由于 MultiViews 和 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]
区别在哪里?我希望这两种方法都可以工作,因为对文件的内部重写位于带有[L] 标志的.htaccess 的最后,因此之后不应该进行任何处理或重定向,对吧?
【问题讨论】:
标签: apache .htaccess mod-rewrite url-rewriting