htaccess:如何避免重复的条件/规则

问题描述 投票:0回答:1

众所周知的问题:Google 索引引擎指出它可以看到 2x2x2=8 个重复的 URL,其中差异在于

  • http - https
  • www - 没有 www
  • root/-root/index.php

(根 URL 重复 8 个,每个其他页面 URL 重复 4 个)

我在 .htaccess 中使用以下工作代码来获取所有重复项的301-redirect

RewriteEngine On

# first, www and root together
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/index.php [R=301,L]

# remove www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

# add index.php to the root url
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ https://%{HTTP_HOST}/index.php [R=301,L]

# finally, force https if none of the earlier conditions are met
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

上面的代码可以很好地使用 301 重定向代码删除所有重复项。然而,我相信它可以用更优雅的方式编写,可能无需加倍重写条件/规则

顺便说一句,我发现数百(!)个帖子提供了相关 .htaccess 语句的建议和示例,并且所有这些帖子要么不完整,要么错误!它们通常会在满足一个条件后停止,或者在每种情况下都不会导致 301 代码。

.htaccess redirect http-status-code-301
1个回答
0
投票

首先(已经在评论中讨论过),你的规范“根”URL 应该只是

/
,而不是
/index.php
。用户不应该在 URL 中看到
index.php
,如果规范是
/index.php
,那么您将必须始终重定向输入/请求根域并共享 URL 的用户(和搜索引擎),包括额外的
index.php
-对任何人都没有好处。您的根的canonical链接元素很简单:

<link rel="canonical" href="https://example.com/">

所有内部链接/锚点都应注明

href="/"
,而不是
href="/index.php"

否则,我在您发布的规则中看到的唯一“小”问题是在 www 和非 www 重定向中以不同的方式对待根目录,并为此制定单独的规则。尽管拥有单独的规则通常很好,但将重定向的数量保持在最低限度,就像它们在这里一样。

如果您没有实施 HSTS(在这种情况下,您需要首先在同一主机上重定向到 HTTPS,然后再进行其他规范化重定向),那么您可以将这些规则合并为一个,并最大限度地减少重定向数量。例如:

RewriteEngine On

# Redirect HTTP and/or WWW and remove "index.php" (if any)
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC,OR]
RewriteCond %{REQUEST_URI} /index\.php$
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.*?)\.?$ [NC]
RewriteRule ^(.*?)(?:(^|/)index\.php)?$ https://%1/$1$2 [R=301,L]

我通过不明确说明域名来保持规则“通用”(但这需要第四个条件来获取主机名减去www子域)。如果规范主机名是硬编码的(取决于服务器/环境),则规则可以“简化”并且可以说“更可靠”。

正则表达式

^(.*?)(?:(^|/)index\.php)?$
匹配任何 URL,但排除捕获子模式 (
index.php
) 中 URL 末尾的可选
/index.php
(或
$1
)。请注意,此正则表达式不仅处理根目录中的
/index.php
,还处理子目录,例如。
/foo/bar/index.php
。当从子目录中删除
$2
时,
index.php
反向引用仅包含斜杠,否则它是

© www.soinside.com 2019 - 2024. All rights reserved.