你的文件在服务器上仍应该具有 .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,例如foo
或bar
应被重写为foo.html
/bar.html
,foo/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 -f
RewriteRule ^(.+[^/])$ $1.html
现在你需要处理的就是那些末尾带斜杠的URL。为此,我们只需添加一个简单的外部重写规则,如果URL实际上不匹配目录,则删除尾随斜杠:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R,L]
该规则仅匹配以斜杠
/
结尾的URL(正则表达式为
/$
),并将斜杠之前的所有内容作为一组捕获(正则表达式为
(.+)
),然后重定向到该组(不包含斜杠)。请注意规则后面的
R
和
L
标志。
R
用于重定向,将浏览器重定向(地址栏中的URL更改)。
L
表示最后一个规则,意味着在此规则之后将不会再应用其他规则,但是在重写之后将再次应用规则,并且这就是另一条规则被应用的地方。
简短概括:
该规则只匹配以斜杠结尾的URL,并将斜杠前面的所有内容作为一个组进行捕获,然后重定向到该组。该规则使用了
R
和
L
标志,
R
表示重定向浏览器,
L
表示此规则为最后一个规则,即在此规则之后不会再应用其他规则。
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+[^/])$ $1.html
domain.tld/test
,但这应该在内部重写为domain.tld/test.html
(不向用户显示,即不更改浏览器地址栏中的内容)?我猜你也想将domain.tld/test.html
重定向到domain.tld/test
?我会写一个答案告诉你如何做到这一点。 - Simon Hänisch