Apache Rewrite - 重定向通配符子域和处理内部 URL 缩短器
Posted
技术标签:
【中文标题】Apache Rewrite - 重定向通配符子域和处理内部 URL 缩短器【英文标题】:Apache Rewrite - Redirect Wildcard Subdomain and Handling Internal URL shortener 【发布时间】:2012-06-14 01:09:13 【问题描述】:我在重定向通配符子域和处理内部 URL 缩短器时遇到问题。
假设我的应用中有一个内部 URL 缩短器
example.com/b/ABCDE
会翻译
example.com/book/12345678-the-book-name
/b/
引用的脚本(我使用可以处理 URL 规则的 php 框架)会将短 ID ABCDE
转换为书的真实 ID 12345678
(以及标题“书名”),然后将其重定向到图书的永久网址example.com/book/12345678-the-book-name
因此,每次我在公告板、微博网站或海报或名片等物理媒体上传播有关书籍的链接时,我都会使用短链接(example.com/b/ABCDE
)而不是永久链接(example.com/book/12345678-the-book-name
)。
接下来,我需要将所有通配符子域重定向到主域(www.example.com
),同时维护请求 URI,例如
http://random.example.com/book/11111111-some-book -> http://www.example.com/book/11111111-some-book
http://123456.example.com/book/22222222-another-book -> http://www.example.com/book/22222222-another-book
http://abcdefg.example.com/book/33333333-another-book-again -> http://www.example.com/book/33333333-another-book-again
在我使用的所有规则之后添加以下规则
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
RewriteEngine on
RewriteCond %HTTP_HOST !^www.example.com [NC]
RewriteRule ^/(.*)$ http://www.example.com/$1 [R=301]
</VirtualHost>
因此,带有 example.com 域且没有前缀的 url 如下所示
http://example.com/book/11111111-some-book
将转换为
http://www.example.com/book/11111111-some-book
而且,另一个后果是,如果内部 URL 缩短器使用没有前缀的普通域,则需要两次重定向才能解决。例如,
http://example.com/b/ABCDE
将首先被重定向到
http://www.example.com/b/ABCDE
然后被重定向到
http://www.example.com/book/12345678-the-book-name
实际上,我不介意两次重定向。但是我的 SEO 顾问说两次重定向对我网站的 SEO 不利。 (我仍然不知道为什么)
所以我尝试将最后一条规则更改为下面
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
RewriteEngine on
RewriteCond %HTTP_HOST ^example.com [NC]
RewriteCond %REQUEST_URI ^/b/(.*)$
RewriteRule . index.php [L]
RewriteCond %HTTP_HOST !^www.example.com [NC]
RewriteRule ^/(.*)$ http://www.example.com/$1 [R=301]
</VirtualHost>
我不太擅长配置 Apache,但是当我在http://htaccess.madewithlove.be/ 中模拟上述规则时,它可以工作。但是当我将它应用到我的服务器时,它给了我 400 Bad Request 用于example.com/p/ABCDE
。
所以,我的问题是
-
我的 SEO 顾问对他的论点是否正确?是否有任何解释可以支持他,或者是否有相反的论点?
为什么服务器给出400 Bad Request?
如何修复重定向?我想保留短 URL(
example.com/b/ABCDE
不带 www
前缀)但仍处于一个重定向中。
【问题讨论】:
如果您只有一个 301 重定向,搜索引擎只会看到一个重定向。内部重定向未显示 - 尽管您可能知道这一点。我不知道两个 301 重定向是否比一个更好/更差。 你不能只处理来自应用程序的重定向吗? 【参考方案1】:你的 SEO 顾问对吗?
作为 SEO 的所有事情,答案涉及一些猜测和假设,但他可能是对的。
当您重定向页面时,您告诉爬虫忘记初始页面并稍后返回以索引目标页面,这会在您的页面首次向世界介绍和页面的实际外观之间引入延迟在搜索结果中。两次重定向意味着您将延迟加倍。根据搜索引擎的“情绪”,这可能会导致您的 SEO 出现显着回归(或者在搜索引擎对重定向进行排序时,您的索引 url 会出现一些混乱)。
为什么会收到 400 响应
如果您查看RewriteRule 的文档,请输入在每个服务器配置中
给定规则 --> 结果替换^/somepath(.*) --> otherpath$1
:无效,不支持^/somepath(.*) --> /otherpath$1
:/otherpath/pathinfo
这意味着,在 vhost conf 中,您必须为您的替代提供一个绝对路径(将返回给 Apache 的最后一个,以前的可以是您喜欢的任何内容)。解决400错误:
RewriteRule . /index.php [L]
如何修复重定向
这将取决于您的 index.php 如何构建其重定向,但设置
ServerName www.example.com
UseCanonicalName On
将$_SERVER["SERVER_NAME"]
设置为www.example.com
,并应生成指向规范域的URL。
潜在的配置
<VirtualHost *:80>
ServerName www.example.com
ServerAlias *.example.com example.com
UseCanonicalName On
RewriteEngine on
#set the document root
DocumentRoot /path/to/the/app
# if something goes wrong, setup logs to track what happens
# comment these lines when you're done
ErrorLog /a/path/to/a/log/file
RewriteLogLevel 5
RewriteLog /a/path/to/another/log/file
# I simplified the conditions, those are equivalent to your rules
# a RewriteRule tries to match against %REQUEST_URI
RewriteCond %HTTP_HOST ^example\.com [NC]
RewriteRule ^/b/ /index.php [L]
RewriteCond %HTTP_HOST !^www\.example\.com [NC]
RewriteRule ^/(.*)$ http://www.example.com/$1 [R=301]
</VirtualHost>
【讨论】:
现在显示 404 Not Found。我尝试将 RewriteRule 更改为RewriteRule . /index.php
,它仍然显示 404。为了给你更多细节,我使用 Yii 框架。这是 Yii 的配置yiiframework.com/doc/guide/1.1/en/topics.url#hiding-x-23x
@PetraBarus 您是否在虚拟主机配置中使用 .htaccess?你能设置一个 ErrorLog 和一个 RewriteLog 来显示哪里出了问题吗?我将它们添加到我的示例配置中
AllowOverride None
导致 apache 无法重新加载并显示“语法错误”消息。但是我查看了错误日志后,日志说找不到路径/var/www/index.php。所以我尝试在配置中添加行DocumentRoot /path/to/the/app
。它就像魅力一样!不再有两次重定向。 http://example.com/b/ABCDE
重定向到 http://www.example.com/book/11111111-some-book
没有中间重定向。但是,如果我不使用AllowOverride None
可以吗? (其实我现在还可以,但是真的可以吗?)
@PetraBarus 糟糕,AllowOverride 仅在目录上下文中可用。你可以安全地删除它,我只是为了绕过潜在的问题才添加它。我将从我的答案中编辑它并添加我之前应该提到的 DocumentRoot。以上是关于Apache Rewrite - 重定向通配符子域和处理内部 URL 缩短器的主要内容,如果未能解决你的问题,请参考以下文章
在通配符 vhost apache (xampp) 设置中重定向子子域