.htaccess 将所有域名及其路径重定向到一个

.htaccess 将所有域名及其路径重定向到一个

我有三个域都指向同一个托管空间,使用A记录进行镜像:

  • example.org
  • example.org.uk
  • example.co.uk

我在根目录 ( /) 上有一个网站,在 上安装了 MediaWiki example.org/members/wiki。我希望所有请求都重定向到 HTTPS 和域.org

.htaccess我已经使用根目录中的网站管理了这个问题:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !example.org$ [NC]
RewriteRule (.*) https://www.example.org/$1 [R=301,L]

但我无法让它与 wiki 一起工作——对.org.uk.co.uk域的请求没有被重定向。

我有.htaccess这个/members

Options -Indexes
RewriteEngine On
RewriteRule ^example.org.uk(/.*)?$     https://www.example.org/$1
RewriteRule ^example.co.uk(/.*)?$ https://www.example.org/$1 

# MediaWiki pretty URL rewrites
RewriteRule ^/?members/wiki(/.*)?$ %{DOCUMENT_ROOT}/members/wiki/index.php [L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/members/wiki/index.php [L]

例如,我想要example.co.uk/members/wiki/My_Page无缝重定向到https://www.example.org/members/wiki/My_Page

谁能告诉我出了什么问题?

答案1

您的问题是 mod_rewrite 指令默认不被继承。您/members/.htaccess文件中的 mod_rewrite 指令完全覆盖了父文件中的 mod_rewrite 指令。访问您的 wiki 时,.htaccess父文件中的 mod_rewrite 指令不会被执行。.htaccess

您可以从/members/.htaccess文件中启用 mod_rewrite 继承(使用RewriteOptions Inherit),但是,如果父文件中的当前指令.htaccess被继承,它们仍然不起作用。(指令被继承,就像它们被直接复制到子目录文件中一样.htaccess。)

要使用 mod_rewrite 继承,您需要更改父.htaccess文件中的以下指令:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !example.org$ [NC]
RewriteRule (.*) https://www.example.org/$1 [R=301,L]

读书:

RewriteEngine On
RewriteCond %{HTTP_HOST} !example\.org$
RewriteRule ^ https://www.example.org%{REQUEST_URI} [R=301,L]

这里的指令RewriteBase是多余的。(除非您有其他指令?)REQUEST_URI服务器变量包含完整的 URL 路径,无论它在哪里使用,与从中捕获的 URL 路径不同RewriteRule 图案.htaccess值得注意的是,在目录/上下文中目录前缀被删除。此NC标记也应在此删除否定条件模式,因为您还想重定向格式错误的请求。

在旁边:但是,这仍然不能规范化 www 子域名,也不会将非 HTTPS 请求重定向到example.org- 这是必需的吗?为此,您需要类似以下内容:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^example\.org$ [OR]
RewriteCond %{HTTPS} !on
RewriteRule ^ https://www.example.org%{REQUEST_URI} [R=301,L]

^注意字符串锚点( )的开头条件模式!^example\.org$)。并针对服务器变量进行额外检查HTTPS(采用“或”操作)。

然后在 中/members/.htaccess,你替换了第一部分(这无论如何都行不通,因为RewriteRule 图案仅匹配 URL 路径,而不匹配主机名):

Options -Indexes
RewriteEngine On
RewriteRule ^example.org.uk(/.*)?$     https://www.example.org/$1
RewriteRule ^example.co.uk(/.*)?$ https://www.example.org/$1 

内容如下:

Options -Indexes
RewriteEngine On
RewriteOptions Inherit

或者,您可以忘记继承并简单地将父 mod_rewrite 指令复制到文件中/members/.htaccess

Options -Indexes
RewriteEngine On
RewriteCond %{HTTP_HOST} !example\.org$
RewriteRule ^ https://www.example.org%{REQUEST_URI} [R=301,L]

# MediaWiki pretty URL rewrites
RewriteRule ^/?members/wiki(/.*)?$ %{DOCUMENT_ROOT}/members/wiki/index.php [L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/members/wiki/index.php [L]

在旁边:但是,这些指令在文件中也不起作用/members/.htaccess?!这些指令适用于服务器配置(或 VirtualHost)上下文。

在每个目录.htaccess文件中,RewriteRule 图案与 URL 路径匹配减去目录前缀。因此,当文件本身位于子目录中时,以 开头的模式^/?members/永远不会匹配。(但是,这在 server/VirtualHost 上下文中可以工作,因为.htaccess/members图案与完整 URL 路径匹配。)

此外,在每个目录.htaccess文件中,你不能重写为绝对文件系统路径,它必须是 document-root 相对 URL 路径。(但是,您可以在 server/VirtualHost 上下文中执行此操作。)

此外,%{DOCUMENT_ROOT}%{REQUEST_URI}是服务器配置中使用的更典型的指令。 更简单的是直接%{REQUEST_FILENAME}使用.htaccess

为了使其正常工作,/members/.htaccess您需要将这些指令更改为更类似于以下内容:

# MediaWiki pretty URL rewrites
RewriteRule ^wiki(/.*)?$ wiki/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ wiki/index.php [L]

相关内容