如何使用Apache mod_rewrite隐藏.html扩展名

时间:2010-01-02 17:29:14

标签: apache mod-rewrite url-rewriting friendly-url

我有少量静态网站,我只想隐藏.html扩展名:

  • 网址/foo获取静态文件/foo.html
  • 浏览器仍会显示网址/foo

然后,客户端可以使用[{1}}样式而不是mydomain.com/foo发送书签。

这听起来非常简单,之前我曾愉快地使用mydomain.com/foo.html(比如使用WordPress或重定向),但事实证明这更难破解。也许我错过了一些非常明显的东西,但我无法在任何地方找到解决方案,而且我一整天都在这里!

我们运行自己的服务器,所以这可以去哪里是最好的地方。

附录

下面检查的解决方案运行正常。然后在运行该网站一段时间后,我发现了两个问题:

  1. 所有页面都开始显得格格不入。我重新加载,清除缓存等,但仍然没有风格。我以前遇到过这个问题,找不到来源。

  2. 有一个名为“gallery”的目录和一个html文件,因此/ gallery链接显示的是目录列表而不是html文件。我应该可以对那个进行排序,但欢迎进一步提示: - )

8 个答案:

答案 0 :(得分:47)

尝试此规则:

RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_FILENAME}.html [L]

这会在附加.html时重写可以映射到现有文件的所有请求。

答案 1 :(得分:32)

以前的答案不会检查请求的路径是否是目录。

如果请求的路径是目录(如原始问题所述),这里是不重写的完全重写条件:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d          # is not directory
RewriteCond %{REQUEST_FILENAME}\.html -f     # is an existing html file
RewriteRule ^(.*)$ $1.html                   # rewrite index to index.html

要成为SEO友好并避免双重内容,重定向.html网址:

# Redirects domain.com/file.html to domain.com/file
RewriteCond %{REQUEST_FILENAME} !-d          # is not directory
RewriteCond %{REQUEST_FILENAME}\.html -f     # is an existing html file
RewriteCond %{REQUEST_URI} ^(.+)\.html$      # request URI ends with .html
RewriteRule (.*)\.html$ /$1 [R=301,L]        # redirect from index.html to index

如果你需要相同的脚本,请看这里: How can I use .htaccess to hide .php URL extensions?

答案 2 :(得分:11)

当网站配置了虚拟主机/文档根目录时,接受的解决方案不起作用。

我使用的是解决方案:

RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_FILENAME}.html [L]

答案 3 :(得分:4)

看看这篇文章http://alexcican.com/post/how-to-remove-php-html-htm-extensions-with-htaccess/我还没有尝试过,但演示似乎很有说服力。

Options -MultiViews 
RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^([^\.]+)$ $1.php [NC,L]

答案 4 :(得分:3)

要从.html请求中删除.*.html个扩展名,您可以在root/.htaccess中使用以下脚本:

RewriteEngine On
RewriteBase /
#1) externally redirect "/file.html" to "/file"
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.html [NC]
RewriteRule ^ %1 [R=301,L]
#2) rewrite  "/file" back to "/file.html"
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*?)/?$ $1.html [NC,L]

答案 5 :(得分:1)

以下示例允许我们将文件存储在磁盘上:

foo.html.php

但是在浏览器中,请将其称为

foo.html

为了让您能够使用此功能,我认为您只需稍微修改一下即可与现有请求相匹配,并使用.html扩展名检查实际文件。

 # These are so we do not need the .php extension
 RewriteCond %{REQUEST_FILENAME} (\.xul|\.html|\.xhtml|\.xml)$',
 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.php -f',
 RewriteRule ^(.*)$ $1.php',

答案 6 :(得分:1)

哇,我很少见到这样一个问题,因为存在这么多"解决方案"在网络上,人们只是滔滔不绝地为他们工作"但是很少有人花时间阅读文档来弄清楚它的作用。例如,这里给出的许多解决方案都不适用于虚拟主机。

经过多次交叉引用和阅读后,我想提供自己的解决方案,并且#34;适用于我"。希望它也适合你。我没有从零开始创建它;我受到所有其他贡献的启发(尽管他们中的大多数没有"为我工作"没有修改)。

[R]

默认情况下R=301标志执行临时(302)重定向;如果您想要永久重定向,请使用R代替{{1}}。

答案 7 :(得分:1)

  • URL / foo获取静态文件/foo.html
  • 浏览器仍然显示URL / foo

Apache可以在没有mod_rewrite的情况下执行此操作,请参阅文档:

多视图

MultiViews的效果如下:如果服务器收到对/ some / dir / foo的请求,如果/ some / dir启用了MultiViews,并且/ some / dir / foo不存在,则服务器读取目录中查找名为foo。*的文件,并有效地伪造了一个类型图,该类型图对所有这些文件进行了命名,为它们分配了与客户端要求通过名称提供其中一种相同的媒体类型和内容编码。然后,选择最适合客户要求的匹配项。

来源:http://httpd.apache.org/docs/current/content-negotiation.html