如何从静态网页的网址中删除.html
?
另外,我需要将.html
的任何网址重定向到没有它的网址。 (即www.example.com/page.html
至www.example.com/page
)。
答案 0 :(得分:78)
我认为对Jon的回答有一些解释是有建设性的。以下内容:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
检查指定的文件或目录是否分别不存在,然后重写规则继续:
RewriteRule ^(.*)\.html$ /$1 [L,R=301]
但这意味着什么?它使用regex (regular expressions)。这是我之前制作的一些东西......
我认为这是正确的。
注意:在测试.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重定向任何网址”)将是完全相同的问题!所以这种解释没有多大意义。另外,他的第一条评论(关于避免无限循环)和他自己的回答似乎证实了这一点。
因此,让我们开始重述问题并分解任务。我们要完成两件事:
.html
是所请求的URL的一部分(例如.html
),则将其删除/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 foundwww.example.com/index.html/
=> 返回 404 not foundwww.example.com/page.html/
=> 返回 404 not foundwww.example.com/test.html
=> 返回 404 not found不再有 500 个错误?
此外,为了帮助您调试重定向,请考虑禁用浏览器中的网络缓存(因为旧的 301 重定向我在缓存中,这可能会引起一些头痛?):