Apache / mod_rewrite:更改 TLD,但保留子域、协议和查询字符串

Posted

技术标签:

【中文标题】Apache / mod_rewrite:更改 TLD,但保留子域、协议和查询字符串【英文标题】:Apache / mod_rewrite: Change TLD, but keep subdomain, protocol and query-string 【发布时间】:2014-04-13 22:29:15 【问题描述】:

我彻底搜索了 ***,发现了大约 100 个 mod_rewrite-questions,但这没有被涵盖...奇怪,因为它似乎很常见。

我的问题:我在主域 (mywebapp.com) 上有一个 Web 应用程序。现在,我想在 .com 域上重定向其他特定于国家/地区的 TLD(例如 .ch)。到目前为止没有什么特别的。但现在到其他标准:

要求

协议应保持不变 查询字符串应保持不变 子域部分应保持不变,因为租户是由那些标识的 只交换 TLD!

示例

所以把它放在一起一些例子应该是怎样的:

http://demo.mywebapp.ch -> http://demo.mywebapp.com http://other.mywebapp.ch/user/profile -> http://other.mywebapp.com/user/profile https://third.mywebapp.ch/about -> https://third.mywebapp.com/about

(url中的空格是为了防止***生成链接)

等等。我真的只需要以协议通用的方式替换 TLD。当然,如果规则集符合 SEO(301),那就太好了。

其他信息/详细信息

这些域当前设置为指向我具有 root 访问权限的同一网络服务器/IP。服务器由 ISPConfig 管理,但 II 也可以手动编辑虚拟主机。

提前致谢!

干杯, 帕斯卡

【问题讨论】:

【参考方案1】:

我遇到了这个脚本的问题。 例如,它可以正常工作,例如: domain.net => domain.com domain.net/something => domain.com/something

但是当我尝试使用子域和不同的***域时,就会发生这种情况 sub.domain.org => subdomain.com 但是 sub.domain.com => sub.domain.com

所以我更改了代码,这是我的版本:

RewriteCond %HTTP_HOST !.*\.com
RewriteCond %HTTPS ^on
RewriteCond %HTTP_HOST (?:([^.]+\.))?mywebapp\..*
RewriteRule ^.* https://%1mywebapp.com%REQUEST_URI [R=302,L]

RewriteCond %HTTP_HOST !.*\.com
RewriteCond %HTTPS !^on
RewriteCond %HTTP_HOST (?:([^.]+\.))?mywebapp\..*
RewriteRule ^.* http://%1mywebapp.com%REQUEST_URI [R=302,L]

希望这对某人有所帮助, rt-2

附:我会在当前答案中添加我的评论,但它说我没有足够的声誉,出于某种原因。

【讨论】:

【参考方案2】:

我认为以下方法可以解决问题:

RewriteEngine on
RewriteBase /

RewriteCond %HTTP_HOST !.*\.com
RewriteCond %HTTPS ^on
RewriteCond %HTTP_HOST (?:([^.]+)\.)?mywebapp\..*
RewriteRule ^.* https://%1mywebapp.com%REQUEST_URI [R=302,L] #removed double slash

RewriteCond %HTTP_HOST !.*\.com
RewriteCond %HTTPS !^on
RewriteCond %HTTP_HOST (?:([^.]+)\.)?mywebapp\..*
RewriteRule ^.* http://%1mywebapp.com%REQUEST_URI [R=302,L] #removed double slash

它是这样说的:

    创建RewriteRule 仅当 %HTTP_HOST 不包含.com 检查协议,只有在 https 时才继续 运行正则表达式检查子域是否存在,如果存在则存储子域(由$1 引用) 手动强制.com,在它前面加上子域,连接%REQUEST_URI,然后重定向(我把它保留为302 Temporary Redirect,所以你可以根据需要使用它。我会去301直到你已经 100% 准备好了)

编辑:我复制了规则集来处理协议问题。所以显然你只能得到最后一个反向引用。这意味着当协议为 https 时,它将覆盖存储在%1 反向引用中的子域。通过为任一协议制定规则集,您可以规避该问题。可能不是最漂亮的方式,但它应该可以完成工作。

【讨论】:

非常感谢山姆!剩下两个问题: 1.你的最后一行在 request_uri 之前不需要斜杠......如果这样,我在重定向后有两个斜杠。删除 rewriterule 中的最后一个斜杠解决了这个问题。 2. 子域还不行。如果我调用 test.mywebapp.ch,我会被重定向到 mywebapp.com(没有任何子域)。你知道如何解决这个问题吗?另一方面,查询部分完美无缺,我从您的解决方案中学到了很多。感谢您抽出宝贵时间! 第三个问题,抱歉:协议现在在重写规则中被硬编码。我需要这是灵活的,因为同时使用了 ssl 和非 ssl。我可以将其保存在 var 中并将其添加到重写规则中吗? @PLM57:我更新了答案以说明httphttps。我注意到我也使用$ 而不是% 进行反向引用,这很可能导致子域不包括在内。让我知道你的效果如何。 谢谢山姆!我还不能测试协议。子域方似乎不起作用。我只被转发到根域(bla.mywebapp.ch -> mywebapp.com)。我发现这条规则仅适用于 1 级子域: RewriteCond %HTTP_HOST ^([^\.]+)\.mywebapp\..* 无论如何......只要我添加协议规则,子域也不会也不再工作了。不知道为什么!?我认为这是一条很好的道路。有什么想法吗? 进一步成功:经过实验,我找到了解决子域问题的规则。它允许仅包含 alpha 的子域(数量不限,或根本没有子域)。我更新了你的答案。唯一剩下的问题:规则不与协议规则合作。一旦我包含它,就没有任何效果了......【参考方案3】:

我的问题略有不同,但我的印象是 RewriteRule 导致协议从 https 切换到 http ,即使我有 canonicalname 。 对我有用的属性是 RequestHeader set ClientProtocol https ,当 LTM 执行 SSL 卸载时。

Listen 8085
<VirtualHost *:8085>
UseCanonicalName On
ServerName https://vip-name
ProxyPreserveHost On
RequestHeader set ClientProtocol https 
RewriteEngine On
#RewriteCond %HTTPS on
RewriteCond %REQUEST_URI !^/abc$ 
RewriteCond %REQUEST_URI ^/xyz$
RewriteRule ^ - [skip=1]
RewriteRule ^/xyz$  https://vip-name/xyz/bc/gui/xyz/language=EN$1 [R,L]
RewriteRule ^/xyz(.*) http://ip1:8085$0 [P,NC]
RewriteRule ^/(.*) http://ip2:8086$0 [P,NC]
</VirtualHost>

【讨论】:

以上是关于Apache / mod_rewrite:更改 TLD,但保留子域、协议和查询字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 apache mod_rewrite 规则重定向到动态 URL(不是经典重定向)?

apache mod_rewrite 模块未安装

Ubuntu系统启用Apache Mod_rewrite模块

域名跳转

Debian/Ubuntu下安装Apache的Mod_Rewrite模块的步骤

Apache如何开启Mod_rewrite模块以及PHPWind伪静态(全伪)