.htaccess 通过隐藏.php和.htm(l)扩展名并重定向到无扩展名URL强制重写URL
以下是我的配置:.htaccess 通过隐藏.php和.htm(l)扩展名并重定向到无扩展名URL强制重写URL,.htaccess,url-rewriting,clean-urls,.htaccess,Url Rewriting,Clean Urls,以下是我的配置: (显然是虚构的名称…)托管在运行Apache并启用mod_rewrite的服务器上 名为“foo”的文件夹(位于并在其中放置.htaccess文件),其中仅包含3种类型的文件.php、.htm、.html .php文件(为了示例起见,我将参考其中一个:phpfile.php) .htm文件(为了示例起见,我将参考其中一个:htmfile.htm) .html文件(为了示例起见,我将参考其中一个:htmlfile.html) 在foo文件夹中,没有文件具有与其他扩展名或没有
- (显然是虚构的名称…)托管在运行Apache并启用mod_rewrite的服务器上
- 名为“foo”的文件夹(位于并在其中放置.htaccess文件),其中仅包含3种类型的文件.php、.htm、.html
- .php文件(为了示例起见,我将参考其中一个:phpfile.php)
- .htm文件(为了示例起见,我将参考其中一个:htmfile.htm)
- .html文件(为了示例起见,我将参考其中一个:htmlfile.html)
- 在foo文件夹中,没有文件具有与其他扩展名或没有扩展名的等效文件(例如foo中既不存在phpfile.htm、phpfile.html也不存在phpfile,只有php.file.php存在)
- 在浏览器的地址栏中输入或或并点击“回车”时:
- 我被重定向到301 to或or(取决于我选择的文件),也就是说,这些latter就是现在显示在地址栏中的URL
- 在浏览器的地址栏中输入或或并点击“回车”时:
- 我没有被重定向,地址栏中没有任何更改,而是服务器只为我提供phpfile.php或htmfile.htm或htmlfile.html,具体取决于我请求的地址
Options +FollowSymLinks
RewriteEngine on
RewriteBase /foo
# Redirect permanently the requests for existing .php files
# to extensionless files (non present on the server)
# so that phpfile.php gets redirected to phpfile
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} \.php$
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)\.php$ $1 [R=301,NC]
# Redirect permanently the requests for existing .htm(l) files
# to extensionless files (non present on the server)
# so that htmfile.htm gets redirected to htmfile
# so that htmlfile.html gets redirected to htmlfile
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} \.html?$
RewriteCond %{REQUEST_FILENAME}\.html? -f
RewriteRule (.*)\.html?$ $1 [R=301,NC]
# Matching requests for non existing extensionless files
# with their existing equivalent on the server
# so that domain.com/foo/phpfile will display
# the contents of domain.com/foo/phpfile.php,
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php [L]
# so that domain.com/foo/htmlfile will display
# the contents of domain.com/foo/htmlfile.html,
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html [L]
# so that domain.com/foo/htmfile will display
# the contents of domain.com/foo/htmfile.htm,
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm [L]
提前感谢您提供的任何帮助/建议。前两条规则中存在一个逻辑缺陷,即存在php或html文件。URI检查实际上也是重写规则模式的副本!f意味着-D您还可以将这些规则合并为一条规则:
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC]
最后两个是可以的,但是如果html请求比php更常见,我会交换顺序
为什么多视图没有帮助
Options+MultiViews
实现了一个称为的概念,在此过程中,Apache调用一个子查询来解析文件名根名称。它所做的一件事是扫描目录中已知的filename.extension组合,因此在本例中,如果存在xxx.php
,并且您的请求是xxx
,那么它将替换xxx.php,并执行内部重定向,然后触发第一条规则,删除.php扩展名会导致出现您看到的错误
因此(i)您需要禁用多视图,以及(ii)同上子查询;(iii)检测并防止重试循环。这是一个可以满足您需求的解决方案:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /foo
RewriteCond %{ENV:REDIRECT_END} =1
RewriteRule ^ - [L,NS]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC,NS]
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php [L,E=END:1,NS]
我想感谢大家的这篇文章,因为它真的帮助了我很多,我使用了下面的一个类似的东西,为我工作
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /
RewriteCond %{ENV:REDIRECT_END} =1
RewriteRule ^ - [L,NS]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC,NS]
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php [L,E=END:1,NS]
这个版本适合我
多谢各位
干杯 谢谢,但是现在当我输入带有文件扩展名的URL时,我收到了一个Firefox错误,因为它没有正确重定向(可能是一个循环),当我输入无扩展名的URL时,我收到的是一个找不到的文件
Options+MultiViews
而不是最后3个重写块。MultiViews没有帮助。无扩展->扩展->无扩展循环仍然发生。我已更新我的答案以满足O/Ps要求。我已经测试了这个镜像我的托管服务,谢谢添加。从来没有真正使用过多视图,所以我不知道扩展名为的文件是通过重写规则传递的。现在我知道了。太糟糕了+2是不可能的:-p非常感谢@TerryE!正如Gerben提到的,+2是不可能的,这太糟糕了:)@Gerben的部分重复,根据这个阈值,.htaccess Q的90%是其他一些.htaccess Q的部分重复。