如何从URL中删除.html?

时间:2011-04-20 12:16:34

标签: html .htaccess

如何从静态网页的网址中删除.html

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

15 个答案:

答案 0 :(得分:78)

我认为对Jon的回答有一些解释是有建设性的。以下内容:

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

检查指定的文件或目录是否分别不存在,然后重写规则继续:

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

但这意味着什么?它使用regex (regular expressions)。这是我之前制作的一些东西...... enter image description here

认为这是正确的。

注意:在测试.htaccess 时,请使用301重定向。使用302直到完成测试,因为浏览器将缓存301s。见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

答案 1 :(得分:68)

使用apache下的.htaccess,你可以像这样重定向:

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

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

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

答案 2 :(得分:64)

这应该适合你:

#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]

答案 3 :(得分:59)

要从您的网址中删除.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扩展名,只需在上面的代码中用 php 替换 html 。< / p>

答案 4 :(得分:16)

您还需要确保自己拥有Options -MultiViews

以上都不适用于标准cPanel主机。

这有效:

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

答案 5 :(得分:13)

感谢您的回复。我已经解决了我的问题。假设我的网页位于 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>

答案 6 :(得分:6)

我使用此.htaccess从我的网址删除.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]

答案 7 :(得分:6)

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

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

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

答案 8 :(得分:3)

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

谢谢

答案 9 :(得分:1)

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

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

接下来从您的所有文件中删除 .html,例如。 test.html 变成了只是测试,如果你想从另一个文件打开一个文件,那么也要从中删除 .html 和文件名

答案 10 :(得分:0)

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

试试这个:)不知道它是否有效。

答案 11 :(得分:0)

重新使用.htaccess重写静态HTML的URL通常不仅不必要,而且对您网站的性能也不利。启用.htaccess也是不必要的安全漏洞-将其关闭可消除许多潜在的问题。可以将每个.htaccess文件的相同规则放到该目录的<Directory>节中,如果再设置AllowOverride None将会提高性能,因为它不需要检查每个文件。 .htaccess文件的目录,并且更加安全,因为攻击者在没有root用户访问权限的情况下无法更改vhost配置。

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

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

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

对于这样的结构:

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

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

但是,如果有人访问旧网址,这将不会重写该URL,因此,如果追溯地将其应用于现有网站,则需要进行重定向。

答案 12 :(得分:0)

很好的问题,但似乎使人们感到困惑。对于认为Dave(OP)正在保存他的HTML页面而没有.html扩展名的人,以及认为他将它们保存为正常的人(使用{{ 1}}),但希望不显示该网址。这个问题的措词可能会好一些,但我认为他的意思很清楚。如果他保存的页面中没有.html,那么他的两个问题(“如何删除.html”)和(如何“使用.html重定向任何网址”)将是完全相同的问题!所以这种解释没有多大意义。另外,他的第一条评论(关于避免无限循环)和他自己的回答似乎证实了这一点。

因此,让我们开始重述问题并分解任务。我们要完成两件事:

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

做任何一件事情都没有困难。 (我们可以仅通过启用MultiViews来实现第二个。)这里的挑战是两者都要做,而不会产生无限循环。

Dave自己的答案完成了工作,但是它很复杂,而且根本不便于携带。 (对不起,戴夫。)ŁukaszHabrzyk似乎已经整理了Anmol的答案,最后Amit Verma对他们两个都做了改进。但是,他们都没有解释如何解决方案来解决基本问题-如何避免无限循环。据我了解,它们之所以起作用是因为/page.html变量保留了来自浏览器的原始请求。这样,条件(THE_REQUEST)仅被触发一次。由于它不会在重写时触发,因此避免了无限循环的情况。但是,然后您要处理完整的HTTP请求-RewriteCond %{THE_REQUEST}GET以及所有请求-部分解释了此页面上一些较丑陋的regex示例。

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

HTTP

让我们分解一下……

第一个规则很简单。条件与任何以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)结尾的URL匹配,并重定向到没有文件扩展名的URL。这是永久重定向,用于指示裁剪的URL是canonical

第二条规则也很简单。仅当请求的文件名不是有效目录(.htm)时,第一个条件才会通过。仅当文件名指向添加了.html扩展名的有效文件(!-d)时,第二个文件才会通过。如果同时通过两个条件,则重写规则只会在文件名中添加“ .html”。然后魔术发生了……-f。是的,这就是防止无限循环的全部方法。 Apache RewriteRule Flags documentation对此进行了解释:

使用[END]标志不仅终止当前的重写周期 处理(如[L]),但也可以防止随后的任何重写 从每个目录(htaccess)上下文中进行处理。

答案 13 :(得分:0)

使用哈希标签。

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

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

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

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

答案 14 :(得分:0)

通过改进@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 not found
  • www.example.com/index.html/ => 返回 404 not found
  • www.example.com/page.html/ => 返回 404 not found
  • www.example.com/test.html => 返回 404 not found

不再有 500 个错误?


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

Screenshot of Google Chrome's console, showing how to disable the "network cache"