.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,具体取决于我请求的地址
我一直在努力尝试这一点,到目前为止,我已经为我的.htaccess文件(位于“foo”文件夹中)提供了这一内容,不幸的是,这只适用于我感兴趣的两种情况中的最后一种(即当我请求“phpfile”时提供“phpfile.php”,当我请求“htmfile”时提供“htmfile.htm”或“htmlfile.html”当我请求“htmlfile”)并且忽略301重定向时:

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的部分重复。