【问题标题】:How to remove .html from URL?如何从 URL 中删除 .html?
【发布时间】:2013-03-21 16:02:17
【问题描述】:

如何从静态页面的 URL 中删除 .html

另外,我需要将任何带有.html 的网址重定向到没有它的网址。 (即 www.example.com/page.htmlwww.example.com/page )。

【问题讨论】:

标签: html .htaccess mod-rewrite


【解决方案1】:

要从您的网址中删除 .html 扩展名,您可以在 root/htaccess 中使用以下代码:

RewriteEngine on


RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ /%1 [NC,L,R]

RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [NC,L]

注意:如果您想删除任何其他扩展名,例如删除 .php 扩展名,只需将上面代码中的 html 替换为 php

另见How to remove .html and .php from URLs using htaccess`

【讨论】:

  • 其他答案都不适合我,但这个答案对我有用,非常感谢!
  • 这个也对我有用。谢谢@starkeen。投个 ^ 票。
  • 工作得非常好。谢谢!
  • 这个删除了我的文件扩展名,但没有重定向到那个页面
【解决方案2】:

通过改进@amit-verma (https://stackoverflow.com/a/34726322/2837434) 的答案,为这个问题做出我自己的贡献:

在我的情况下,我遇到了一个问题,即RewriteCond %{REQUEST_FILENAME}.html -f 正在触发(相信文件存在),即使我没想到它:

%{REQUEST_FILENAME}.html 在所有这些情况下都给了我/var/www/example.com/page.html

  • www.example.com/page(预计)
  • www.example.com/page/(也很期待)
  • www.example.com/page/subpage(不是预期的)

所以它试图加载的文件(相信如果是/var/www/example.com/page.html)是:

  • www.example.com/page => /var/www/example/page.html(好的)
  • www.example.com/page/ => /var/www/example/page/.html(不好)
  • www.example.com/page/subpage => /var/www/example/page/subpage.html(不好)

只有第一个实际上指向一个现有文件,其他请求给了我 500 个错误,因为它一直认为该文件存在并重复附加 .html

我的解决方案是将RewriteCond %{REQUEST_FILENAME}.html -f替换为RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f

这是我的整个.htaccess(我还添加了一条规则,将用户从/index 重定向到/):

# Redirect "/page.html" to "/page" (only if "/pages.html" exists)
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{THE_REQUEST} /(.+)\.html [NC]
RewriteRule ^(.+)\.html$ /$1 [NC,R=301,L]

# redirect "/index" to "/"
RewriteRule ^index$ / [NC,R=301,L]

# Load "/page.html" when requesting "/page" (only if "/pages.html" exists)
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f
RewriteRule ^ /%{REQUEST_URI}.html [QSA,L]

这是一个结果示例,可帮助您理解所有案例:

考虑到我的服务器上只有 2 个 html 文件(index.html 和 page.html)

  • www.example.com/index.html => 重定向到 www.example.com
  • www.example.com/index => 重定向到 www.example.com
  • www.example.com => 渲染 /var/www/example.com/index.html
  • www.example.com/page.html => 重定向到www.example.com/page
  • www.example.com/page => 渲染/var/www/example.com/page.html
  • www.example.com/page/subpage => 返回 404 未找到
  • www.example.com/index.html/ => 返回 404 未找到
  • www.example.com/page.html/ => 返回 404 未找到
  • www.example.com/test.html => 返回 404 未找到

不再有 500 个错误?


另外,为了帮助您调试重定向,请考虑在浏览器中禁用网络缓存(因为旧的 301 重定向我在缓存中,这可能会引起一些头痛 ?):

【讨论】:

  • 感谢您的简要解释。一个修复,RewriteRule ^index$ / [NC,R=301,L] 到 RewriteRule ^index.*$ / [NC,R=301,L] 到避免加载 index.php。所以现在 index 或 index.php 或 index.html 将被重定向到主页?
【解决方案3】:

首先创建一个.htaccess文件并将内容设置为-

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html

下一步从所有文件中删除 .html,例如。 test.html 变成了只是测试,如果你想从另一个文件中打开一个文件,那么也可以从中删除 .html 并只删除文件名

【讨论】:

    【解决方案4】:

    使用井号标签。

    可能不是你想要的,但它解决了删除扩展的问题。

    假设您有一个保存为 about.html 的 html 页面,并且您不想要那个讨厌的扩展,您可以使用哈希标签并重定向到正确的页面。

    switch(window.location.hash.substring(1)){
          case 'about':
          window.location = 'about.html';
          break;
      }
    

    路由到yoursite.com#about 会将您带到yoursite.com/about.html。我用它来使我的链接更干净。

    【讨论】:

      【解决方案5】:

      使用.htaccess 重写静态HTML 的URL 通常不仅没有必要,而且对您的网站性能不利。启用.htaccess 也是一个不必要的安全漏洞——关闭它可以消除大量潜在问题。每个.htaccess 文件的相同规则可以改为进入该目录的<Directory> 部分,如果然后设置AllowOverride None,它会更高效,因为它不需要检查每个目录的.htaccess文件,并且更安全,因为攻击者无法在没有 root 访问权限的情况下更改 vhost 配置。

      如果您在 VPS 环境中不需要.htaccess,您可以完全禁用它并从您的网络服务器获得更好的性能。

      您需要做的就是从这样的结构中移动您的单个文件:

      index.html
      about.html
      products.html
      terms.html
      

      到这样的结构:

      index.html
      about/index.html
      products/index.html
      terms/index.html
      

      然后,您的 Web 服务器将呈现相应的页面 - 如果您加载 /about/,它会将其视为 /about/index.html

      但是,如果有人访问旧的 URL,这不会重写 URL,因此如果它被追溯应用于现有站点,则需要重定向。

      【讨论】:

      • 如果您正在管理 VPS,为什么不将重写添加到 Apache 配置文件 (httpd.conf),而不是 .htaccess?如果您不是管理员,当然……您的性能会受到一点影响。我想您需要权衡一下为您网站上的每个文件创建目录的不切实际情况。
      • @Kal 实际上我会将重写放在每个站点的虚拟主机配置中,而不是 https.conf。然后它们将与 .htaccess 中的基本相同。
      • 我的意思是 httpd.conf
      • 而且您不需要为您网站上的每个文件创建一个目录 - 最多可以将您的所有规则移动到您的虚拟主机配置中的 <Directory> 指令中。
      • 澄清一下,我也不会修改 httpd.conf 主文件。我使用 DirectAdmin,每个用户都有自己的 httpd.conf 文件。关键是,配置您的 VirtualHost 条目(如果可以的话)可以缓解您提出的性能问题。听起来我们同意这一点。
      【解决方案6】:

      好问题,但它似乎让人们感到困惑。那些认为 Dave(OP)正在保存他的 HTML 页面没有.html 扩展名的人和那些认为他正常保存它们的人(使用.html)的答案几乎平分秋色。 ,但希望 URL 不显示。虽然这个问题可以措辞更好一些,但我认为他的意思很清楚。如果他在没有.html 的情况下保存页面,他的两个问题(“如何删除.html”)和(如何“使用.html 重定向任何网址”)将是完全相同的问题!所以这种解释没有多大意义。此外,他的第一条评论(关于避免无限循环)和他自己的回答似乎证实了这一点。

      因此,让我们首先重新表述问题并分解任务。我们想要完成两件事:

      1. 如果 .html 是请求的 URL 的一部分(例如 /page.html),则明显删除它
      2. 将裁剪后的 URL(例如 /page)指向实际文件 (/page.html)。

      做这两件事都没有什么难的。 (我们可以通过启用MultiViews 来实现第二个。)这里的挑战是在不创建无限循环的情况下两者

      Dave 自己的回答完成了工作,但它非常复杂,而且一点也不便携。 (对不起,戴夫。) Łukasz Habrzyk 似乎已经清理了 Anmol 的答案,最后 Amit Verma 对他们俩都进行了改进。然而,他们都没有解释他们的解决方案如何解决基本问题——如何避免无限循环。据我了解,它们之所以有效,是因为 THE_REQUEST 变量包含来自浏览器的原始请求。因此,条件 (RewriteCond %{THE_REQUEST}) 只会被触发一次。由于它不会在重写时触发,因此您避免了无限循环的情况。但随后您将处理完整的 HTTP 请求——GETHTTP 等等——这部分解释了此页面上一些更丑陋的正则表达式示例。

      我将提供另一种方法,我认为它更容易理解。我希望这可以帮助未来的读者理解他们正在使用的代码,而不是仅仅复制和粘贴他们几乎不理解的代码并希望获得最好的结果。

      RewriteEngine on
      
      # Remove .html (or htm) from visible URL (permanent redirect)
      RewriteCond %{REQUEST_URI} ^/(.+)\.html?$ [nocase]
      RewriteRule ^ /%1 [L,R=301]
      
      # Quietly point back to the HTML file (temporary/undefined redirect):
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME}.html -f
      RewriteRule ^ %{REQUEST_URI}.html [END]
      

      让我们分解一下……

      第一条规则非常简单。该条件匹配任何以.html(或.htm)结尾的URL,并重定向到不带文件扩展名的URL。这是一个永久重定向,表示裁剪后的 URL 是 canonical

      第二条规则也很简单。只有当请求的文件名不是有效目录 (!-d) 时,第一个条件才会通过。仅当文件名引用添加了 .html 扩展名的有效文件 (-f) 时,第二个才会通过。如果 两个 条件都通过,重写规则只需将“.html”添加到文件名中。然后神奇的事情发生了……[END]。是的,这就是防止无限循环所需要的一切。 Apache RewriteRule Flags documentation 解释它:

      使用 [END] 标志不仅会终止当前轮次的重写 处理(如 [L]),但也防止任何后续重写 在每个目录 (htaccess) 上下文中发生的处理。

      【讨论】:

        【解决方案7】:

        对于那些使用 Firebase 托管的人,此页面上没有任何答案。因为您不能在 Firebase 托管中使用 .htaccess。您必须配置 firebase.json 文件。只需在文件中添加"cleanUrls": true 行并保存即可。就是这样。

        添加行后 firebase.json 将如下所示:

        {
          "hosting": {
            "public": "public",
            "cleanUrls": true, 
            "ignore": [
              "firebase.json",
              "**/.*",
              "**/node_modules/**"
            ]
          }
        }
        

        【讨论】:

          【解决方案8】:

          我认为对Jon's answer 的一些解释将是建设性的。以下:

          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          

          检查如果指定的文件或目录分别不存在,则重写规则继续:

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

          但这意味着什么?它使用regex (regular expressions)。这是我之前做的一个小东西……

          认为没错。

          注意:在测试您的 .htaccess 时,不要使用 301 重定向。使用 302 直到完成测试,因为浏览器会缓存 301。见https://stackoverflow.com/a/9204355/3217306

          更新:我有点误会了,. 匹配除换行符之外的所有字符,因此包括空格。另外,here is a helpful regex cheat sheet

          来源:

          http://community.sitepoint.com/t/what-does-this-mean-rewritecond-request-filename-f-d/2034/2

          https://mediatemple.net/community/products/dv/204643270/using-htaccess-rewrite-rules

          【讨论】:

          • 精湛的图表帮助解释答案。
          • 301s 和浏览器缓存的提示解决了我的问题。
          • @KnocksX 我不再是网站管理员,无法提供帮助
          • 不错的图形,但就像它引用的答案一样,这个问题误解了实际问题,并假设所有文件都保存在没有 .html 扩展名的情况下。请参阅my answer 以获得更详尽的说明。
          • 对我不起作用。我该如何调试它?
          【解决方案9】:

          要从您的 URL 中删除 .html 扩展名,您可以在 root/htaccess 中使用以下代码:

          #mode_rerwrite start here
          
          RewriteEngine On
          
          # does not apply to existing directores, meaning that if the folder exists on server then don't change anything and don't run the rule.
          
          RewriteCond %{REQUEST_FILENAME} !-d
          
          #Check for file in directory with .html extension 
          
          RewriteCond %{REQUEST_FILENAME}\.html !-f
          
          #Here we actually show the page that has .html extension
          
          RewriteRule ^(.*)$ $1.html [NC,L]
          

          谢谢

          【讨论】:

          • "检查目录中带有 .html 扩展名的文件" - 但条件是检查文件不存在!您需要删除 CondPattern 上的 ! 前缀。
          【解决方案10】:

          您还需要确保拥有Options -MultiViews

          在标准的 cPanel 主机上,上述方法都不适合我。

          这行得通:

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

          【讨论】:

          • 在上面的所有答案中,这个答案终于奏效了。我相信是因为我的网站是使用 cPanel 托管在 Godaddy 上的。关键是Options -MultiViews
          • 是的,本节中的任何内容都不起作用期待这个答案!你拯救了这一天!
          • 谢谢伙计。我不确定为什么其他人没有按预期工作。
          • 如何在 url 的末尾加上斜杠? site.com/test 正在工作,但 site.com/test/ 不是... 编辑:似乎 RewriteRule ^([^\.]+)/$ $1.html [NC,L] 可以解决问题。可以吗?
          【解决方案11】:

          感谢您的回复。我已经解决了我的问题。假设我的页面位于 http://www.yoursite.com/html 下,则适用以下 .htaccess 规则。

          <IfModule mod_rewrite.c>
             RewriteEngine On
             RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /html/(.*).html\ HTTP/
             RewriteRule .* http://localhost/html/%1 [R=301,L]
          
             RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /html/(.*)\ HTTP/
             RewriteRule .* %1.html [L]
          </IfModule>
          

          【讨论】:

            【解决方案12】:

            在 apache 下使用 .htaccess,您可以像这样进行重定向:

            RewriteEngine On
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteRule ^(.*)\.html$ /$1 [L,R=301] 
            

            至于从url中删除.html,只需链接到没有.html的页面

            <a href="http://www.example.com/page">page</a>
            

            【讨论】:

            • 这对我没有任何作用。是否有某些原因它不起作用?
            • 您有请求链接的实际文件吗?这将触发!-f
            • @Martijn,我认为这就是重点——你在/page.html 有一个文件,但你想用/page 链接到它。我怀疑这个答案误解了这个问题,并假设 OP 在没有 .html 扩展名的情况下保存了他的页面(正如我所读的那样,情况并非如此。)
            【解决方案13】:

            这应该适合你:

            #example.com/page will display the contents of example.com/page.html
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_FILENAME}.html -f
            RewriteRule ^(.+)$ $1.html [L,QSA]
            
            #301 from example.com/page.html to example.com/page
            RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/
            RewriteRule ^(.*)\.html$ /$1 [R=301,L]
            

            【讨论】:

            • 我在 Godaddy 中使用此代码获得了 404,我将其修复:选项 +FollowSymLinks -MultiViews -Indexes 在最顶部。
            • 我认为这是最好最完整的答案,谢谢!
            • 我尝试在 localhost 中执行此操作,但它不起作用,我还需要做其他事情吗,我是否必须链接 .htaccess 文件,或者页面如何识别它?
            • 如何将 .php 扩展名添加到 #301 从 example.com/page.html 到 example.com/page ,可以吗?
            【解决方案14】:

            我使用这个 .htacess 从我的 url 站点中删除 .html 扩展,请验证这是正确的代码:

                RewriteEngine on
            RewriteBase /
            RewriteCond %{http://www.proofers.co.uk/new} !(\.[^./]+)$
            RewriteCond %{REQUEST_fileNAME} !-d
            RewriteCond %{REQUEST_fileNAME} !-f
            RewriteRule (.*) /$1.html [L]
            RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^.]+)\.html\ HTTP
            RewriteRule ^([^.]+)\.html$ http://www.proofers.co.uk/new/$1 [R=301,L]
            

            【讨论】:

            • 这似乎对我有用,与此处介绍的其他解决方案不同,谢谢。我要补充一点,尽管您仍然需要更新 HTML 中的链接(因此,如果您最初将 .html 文件链接为 ,则应该更新它作为 example.com/page1"></a> 然后它会工作。)
            • 对我来说核心变化是RewriteBase / 位。不幸的是,我不明白它为什么会起作用,但我想我很快就会学会。
            【解决方案15】:
            RewriteRule /(.+)(\.html)$ /$1 [R=301,L] 
            

            试试这个 :) 不知道行不行。

            【讨论】:

            • 如果您不确定它是否有效,则不应将其发布为答案。
            猜你喜欢
            • 1970-01-01
            • 2017-03-02
            • 2012-08-29
            • 2017-02-27
            • 2012-05-28
            • 2021-09-03
            相关资源
            最近更新 更多