使用htaccess文件删除HTML扩展名

4
我知道这是一个非常普遍的话题,但没有任何解决方案适用于我。 我尝试了几个答案:

答案1

答案2

答案3

以及引荐链接。

我正在使用的htaccess代码:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)\.html$ /$1 [L,R=301] 

然后我将我的链接从services.html更改为services,即删除扩展名,并使用ftp从文件名中删除扩展名。
然后我在浏览器中看到的是页面代码而不是实际页面。
我已检查了我的服务器上的mod_rewrite,并且它可以正常工作,使用以下代码。
RewriteEngine On
Options +FollowSymLinks
RewriteRule ^joomla\.html http://www.joomla.org/? [R=301,L]

你的原始链接是什么样子的? - Abhishek Gurjar
我认为你想要的是在浏览器中输入 domain.tld/test,但这应该在内部重写为 domain.tld/test.html(不向用户显示,即不更改浏览器地址栏中的内容)?我猜你也想将 domain.tld/test.html 重定向到 domain.tld/test?我会写一个答案告诉你如何做到这一点。 - Simon Hänisch
2个回答

14

你的文件在服务器上仍应该具有 .html 扩展名,否则服务器/浏览器将不会将其解释为 HTML,而是作为文本显示(这就是你在浏览器中看到代码的原因)。因此,请再次使用 ftp 在服务器上重命名文件。

为了让你的服务器在访问 /test 时提供文件 /test.html,你需要进行内部重写,即:

RewriteRule ^test[^/]$ test.html
^用于匹配字符串的开头,$用于匹配结尾,因此只有在url完全匹配test时才会进行重写。它将请求重写为test.html。重写是内部的,这意味着它不会重定向浏览器(地址栏中的url不会改变)。还有外部重写(规则后面附加[R]),它会重定向浏览器。
该规则还仅匹配不以斜杠结尾的url([^/]表示“非斜杠”)。稍后我们将处理以斜杠结尾的url。
您可以为每个要进行重写的页面创建自定义RewriteRule
RewriteRule ^foo[^/]$ foo.html
RewriteRule ^bar[^/]$ bar.html

如果您有许多页面,则需要进行大量的工作,因此您可能希望重写所有URL,例如foobar应被重写为foo.html/bar.htmlfoo/bar应被重写为foo/bar.html

您还可以使用正则表达式来匹配所有请求。但是,您应该首先检查foo实际上是否是一个目录(这可能包含一个index.html并且是您想要提供的子目录)。同时,您需要检查foo是否确实是您服务器文件系统中的文件。有两个重写条件需要检查(请参见RewriteCond指令):

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
现在,您可以为所有请求添加重写规则:

现在,您可以为所有请求添加重写规则:

RewriteRule ^(.+[^/])$ $1.html

$1 是第一个捕获组的内容,在正则表达式中,捕获组是放置在 () 括号内的表达式。. 匹配任何字符,+ 修饰符表示 "一个或多个"。

请注意,这会导致重写循环结果为500错误(参见此答案),因此您还需要添加重写条件来检查文件系统上是否实际存在 <request>.html 文件:

RewriteCond %{REQUEST_FILENAME}.html -f

此外,您可能不想重写已经具有 .html 扩展名的 URL。我认为这是不必要的,因为您已经有了上面的规则,在这种情况下会检查 <file>.html.html,这可能不应该存在。但是如果您必须处理这个问题,您可以添加另一个条件:

RewriteCond %{REQUEST_FILENAME} !^.+\.html$

所以,将所有内容综合起来,你的重写规则看起来像这样:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !^.+\.html$ # not really necessary
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+[^/])$ $1.html

现在你需要处理的就是那些末尾带斜杠的URL。为此,我们只需添加一个简单的外部重写规则,如果URL实际上不匹配目录,则删除尾随斜杠:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R,L]
该规则仅匹配以斜杠/结尾的URL(正则表达式为/$),并将斜杠之前的所有内容作为一组捕获(正则表达式为(.+)),然后重定向到该组(不包含斜杠)。请注意规则后面的RL 标志R用于重定向,将浏览器重定向(地址栏中的URL更改)。 L表示最后一个规则,意味着在此规则之后将不会再应用其他规则,但是在重写之后将再次应用规则,并且这就是另一条规则被应用的地方。

简短概括:


该规则只匹配以斜杠结尾的URL,并将斜杠前面的所有内容作为一个组进行捕获,然后重定向到该组。该规则使用了RL标志,R表示重定向浏览器,L表示此规则为最后一个规则,即在此规则之后不会再应用其他规则。
RewriteBase /

# handle trailing slashes (if not a directory)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R,L]

# rewrite rule that internally adds the .html extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+[^/])$ $1.html

嘿,多么好的答案,谢谢!总体来说它起作用了!所以我再次将 .html 扩展名添加到 ftp 文件中,然后从我的锚点中删除了 .html 扩展名。所以我的链接看起来像 <a href="work">,这给了我想要的没有 .html 扩展名的 mydomain.com/work 的 URL。只有一个奇怪的链接无法工作:<a href="services"> 显示页面的代码,尽管在 ftp 中的文件是 services.html。我正在使用 Foundation 框架。 - xbass540
我刚刚添加了有关如何处理尾部斜杠的说明。你的服务器上可能有两个文件,即services.htmlservices?Foundation框架不会影响您的重写规则。 - Simon Hänisch
@SimonHänisch:听起来相当不可能。请确保您的浏览器缓存没有误导您。 - CBroe
@xbass540 我不知道有没有一种方法可以将 <file>.html 重定向到只有 <file>,而不会创建一个重定向循环(即 <file> 被重写为 <file>.html,这会再次触发重定向等等)。我添加了一个条件,只匹配不以 .html 结尾的文件。所以这是我的最终答案。 - Simon Hänisch
@SimonHänisch 我尝试了另一个浏览器并清除了浏览器缓存。唯一一份持续显示页面代码的文件是services。如果我访问services.html,一切正常。所有其他文件都可以正常工作。 - xbass540
显示剩余7条评论

-1

就像@simon建议的那样,正确的文件是:

# handle trailing slashes (if not a directory)
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.+)/$ $1 [R,L]

# rewrite rule that internally adds the .html extension

RewriteCond %{REQUEST_FILENAME} !-d

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME}.html -f

RewriteCond %{REQUEST_FILENAME} !^.+\.html$

RewriteRule ^(.+[^/])$ $1.html

此外,我还需要通过FTP从服务器上删除所有具有相同名称的文本文件。


@simonHanisch 我发现了上述文件的一个回退,关于斜杠的修复(如果不是目录)。当我访问example.com/services/时,它会将我重定向到example.com/home/myftpuser/public_html/services,并且我会收到404错误。 - xbass540
你可以尝试使用 RewriteBase / 吗?如果你使用符号链接,你可能还需要 Options +FollowSymLinks... 还要注意 REQUEST_FILENAMEREQUEST_URI 之间的区别。 - Simon Hänisch
@Simon Hanisch:RewriteBase / 真是太棒了。谢谢 Simon。 - xbass540
好的。请记住,如果您将页面移动到子文件夹中,例如 domain.tld/my-site/,则需要设置 RewriteBase /my-site/。很高兴能帮助到您。 - Simon Hänisch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接