【问题标题】:How to hide the .html extension with Apache mod_rewrite如何使用 Apache mod_rewrite 隐藏 .html 扩展名
【发布时间】:2010-12-31 19:42:21
【问题描述】:

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

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

然后客户端可以发送mydomain.com/foo 样式的书签,而不是mydomain.com/foo.html

这听起来很简单,我之前很高兴地使用过mod_rewrite(比如使用 WordPress 或重定向),但事实证明这比我想象的更难破解。也许我遗漏了一些非常明显的东西,但我在任何地方都找不到解决方案,而且我整天都在努力!

我们运行自己的服务器,所以它可以去任何最好的地方。

附录

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

  1. 所有页面都开始出现无样式。我重新加载,清除缓存等,但仍然没有风格。我以前也遇到过这个问题,找不到源。

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

【问题讨论】:

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


    【解决方案1】:

    试试这个规则:

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

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

    【讨论】:

    • 谢谢!只需将模式更改为 '(.[a-z]+)',因为所有 html 文件仅包含这些字符。现在出现了新问题,最糟糕的是没有 CSS(这最初出现在重新加载时,然后打开和关闭样式,现在所有文件都没有样式,所以我猜早期的视图正在获取缓存的 CSS 文件?)。
    • @DaveEveritt 我遇到了同样的 CSS 问题,只有当我在 URL 中附加一个斜杠时,在这种情况下,所有相关链接都被认为位于子目录中,包括 CSS。你找到解决方法了吗?
    • @LazloBonin 一种解决方案是不使用绝对路径而不是相对路径。或者显式设置具有适当路径的基本 URL,以便从基本 URL 路径而不是当前 URL 路径解析相对路径。
    • @AshMenon 那是否定运算符:仅当以下不匹配时才适用。
    • @AshMenon 规则的意思是:仅在.html 尚未以.html 结尾并且结果文件存在时才附加。
    【解决方案2】:

    这是一个允许我们将文件存储在磁盘上的示例:

    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',
    

    【讨论】:

      【解决方案3】:

      前面的答案没有检查请求的路径是否是目录。

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

      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?

      【讨论】:

      • 您需要两个规则块。第一个在内部将index 重写为index.html,因此用户看不到它。第二个块执行从 index.htmlindex 的 301 重定向。
      • 请注意 - 至少从 Apache 2.2.23 开始 - 显然不支持内联 cmets,因此上述定义将破坏 .htaccess 文件并导致 500 错误,除非您删除内联 cmets。
      • 如果我未修改地使用您的定义,则不会重定向以“.html”结尾的路径。如果我从 2nd 块中删除 RewriteCond %{REQUEST_FILENAME}\.html -f,我最终会出现重定向循环(从 Apache 2.2.23 开始)。
      • 上面的 SEO 解决方案不起作用(正如其他一些人指出的那样)。试试RewriteCond %{THE_REQUEST} ^[A-Z]+\ (/[^\ ]*)\.html[?\ ],然后是RewriteRule (.*)\.html$ /$1 [R=301,L] - 对我有用:)
      • @PaddyMann,你为什么需要第一个RewriteCond?它显然会检查请求是否以.html 结束。但这不是RewriteRule 本身的规则部分吗? RewriteCond 不是多余的吗?
      【解决方案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]
      

      【讨论】:

        【解决方案5】:

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

        有我使用的解决方案:

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

        【讨论】:

          【解决方案6】:

          要从.*.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]
          

          【讨论】:

          • 谢谢,虽然这是一个老问题,我使用Nanoc(静态网站生成器)来处理这样的网站。我试过了,但衍生问题仍然存在——我的风格完全消失了。
          • 欢迎您@DaveEveritt!要在重写的 url 上修复您的样式、js、图像和其他相关资源,您可以在网页的 head 部分添加一个基本标签<base href="/"> 以获取更多信息..阅读我在这篇文章中的回答stackoverflow.com/questions/31241701/…
          • 又试了一次,但还是不开心。这是一个旧站点,我使用的是 SSI(在您的示例中将 .html 更改为 .shtml)并且已经将所有主要小节移动到它们自己的目录中,但是这些目录中的非索引 .shtml 页面会从它们的包含目录中删除URL 如此 404,并且“/styles/body.css”仍然无法在整个站点中加载。无论如何,感谢您的提示,但我现在会放弃这个,因为该网站将在某个时候重新制作!
          【解决方案7】:

          哇,我很少看到这样的问题,网络上有这么多“解决方案”,人们只是抛出“对他们有用”的东西,但很少有人花时间阅读文档来弄清楚什么确实如此。例如,这里给出的许多解决方案都不适用于虚拟主机。

          经过大量的交叉引用和阅读,我想贡献我自己的“适合我”的解决方案。希望它也适合你。我不是从头开始创建它的。我受到了所有其他贡献的启发(尽管它们中的大多数没有经过修改就“为我工作”)。

          RewriteEngine on
          
          #if foo requested, return foo.html contents
          RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
          RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.html -f
          RewriteRule ^(.*)$ $1.html [L]
          
          #redirect foo.html to foo
          RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
          RewriteRule ^(.+)\.html$ $1 [R,L]
          

          [R] 标志默认执行临时 (302) 重定向;如果您想要永久重定向,请使用 R=301 代替 R

          【讨论】:

          • 试过了,同样的问题!没关系,因为我正在重写网站,无论如何谢谢:-)
          • 对我来说,这会重定向到文件的整个路径(例如,/index.html 变为 /var/www/htdoc/index
          • 它不起作用......现在它不断将 index.html 重定向到根目录。我该如何解决?
          【解决方案8】:
          • 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

          【讨论】:

            猜你喜欢
            • 2013-03-13
            • 1970-01-01
            • 2011-09-08
            • 1970-01-01
            • 1970-01-01
            • 2012-11-30
            • 1970-01-01
            • 2013-05-02
            • 2012-04-19
            相关资源
            最近更新 更多