你的文件应该仍然有.html
服务器上的扩展名,否则服务器/浏览器不会将其解释为 html,而是文本(这就是您在浏览器中看到代码的原因)。因此,再次使用 ftp 重命名服务器上的文件。
为了让您的服务器提供文件/test.html
当网址/test
被访问时,您想在内部重写它,即:
RewriteRule ^test[^/]$ test.html
The ^
是匹配字符串的开头,$
匹配结尾,所以只有当 url 完全匹配时才会重写test
。它将将该请求重写为test.html
。重写是内部的,这意味着它不会重定向浏览器(地址栏中的 URL 不会改变)。还有外部重写([R]
附加到规则中),它会重定向浏览器。
此规则也仅匹配不以尾部斜杠结尾的网址 ([^/]
意思是“不是斜线”)。稍后我们将处理带有斜杠的 url。
您可以创建一个自定义RewriteRule
对于要重写的每个页面:
RewriteRule ^foo[^/]$ foo.html
RewriteRule ^bar[^/]$ bar.html
如果您有很多页面,这将是一项艰巨的工作,因此您可能需要重写所有网址,例如foo
or bar
应该重写为foo.html
/ bar.html
, and foo/bar
应该重写为foo/bar.html
.
您还可以使用正则表达式来匹配所有请求。但你应该首先检查是否foo
实际上不是一个目录(它可能包含index.html
并成为您想要服务的子目录)。您还想检查是否foo
实际上并不是服务器文件系统上的文件。有两个重写条件来检查(请参阅RewriteCond指示 https://httpd.apache.org/docs/current/mod/mod_rewrite.html):
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
现在您可以为所有请求添加重写规则:
RewriteRule ^(.+[^/])$ $1.html
$1
是第一个捕获组的内容,正则表达式中的捕获组是放置在()
括号。.
匹配任何字符,+
修饰语的意思是“一个或多个”。
请注意,这会导致重写循环,从而导致 500 错误(看到这个答案 https://stackoverflow.com/a/12463742/2897426),所以你还需要添加一个重写条件来检查是否<request>.html
文件实际上存在于文件系统上:
RewriteCond %{REQUEST_FILENAME}.html -f
另外,您可能不想重写已经有.html
扩大。我认为没有必要,因为您已经有了上面的规则,在这种情况下会检查<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 实际上与目录不匹配,则删除尾部斜杠:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R,L]
该规则仅匹配以以下结尾的网址/
(regex /$
)并捕获尾部斜杠之前的所有内容作为一个组(正则表达式(.+)
),然后重定向到组(不包含斜杠)。注意R
and L
flags https://httpd.apache.org/docs/2.2/rewrite/flags.html规则的背后。R
用于重定向,即重定向浏览器(地址栏中的 url 发生变化)。L
是最后一个,意味着在此之后不会应用其他规则,但重写后将再次应用规则,这就是应用其他规则的地方。
TL;DR
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