我正在建立一个网站OpenShift。它在 Apache 2.2.15 下运行,但我无权访问 Apache 根目录或日志,因此我尝试在站点根目录下的 .htaccess 文件中模拟虚拟目录。大部分运行良好,但有一个重定向问题我无法解决。
该网站的结构如下:
应用程序根目录/repo- .htaccess 所在的站点根目录
app-root/repo/domain_example
应用程序根目录/repo/domain_example/main- 主网站 (WordPress)
在 WordPress 中,我的博客位于 www.example.com/blog 下,但在迁移到 WordPress 之前,我在 blogs.example.com 子域中有一些文章。为了维护链接,我在 .htaccess 中设置了重定向命令。它们在我以前的共享托管提供商上运行良好。它们甚至在 OpenShift 上运行良好前我添加了 www.example.com 作为 OpenShift 别名。但是,自从添加别名以来,如果原始主机名以 blogs 开头,我就无法强制 .htaccess 返回 www。
来自 Apache重定向文档:
新的 URL 应该是以方案和主机名开头的绝对 URL。在 Apache HTTP Server 2.2.6 及更高版本中,也可以使用以斜杠开头的 URL-path,在这种情况下将添加当前服务器的方案和主机名。然后,任何以 URL-path 开头的请求都将在目标 URL 的位置向客户端返回重定向请求。
我的期望是:如果我提供绝对 URL 作为目标,则重定向应将该 URL 返回给客户端。然后客户端可以使用正确的 URL 重新发出请求。
怎么了:重定向正在发生(我在 Firebug 中看到 302),但它指向源域,而不是目标。尽管我提供了绝对 URL,但它似乎在执行第二位(使用“当前服务器的方案和主机名”)。
以下是我的.htaccess 的摘录:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# This section from https://my.bluehost.com/cgi/help/347#redirect
RewriteCond %{HTTP_HOST} ^(www.)?example\.com$
RewriteCond %{REQUEST_URI} !^/domain_example/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /domain_example/main/$1
RewriteCond %{HTTP_HOST} ^(www.)?example\.com$
RewriteRule ^(/)?$ domain_example/main/index.php [L]
# blogs.example.com redirects
redirect 302 /mark/post/Check-Windows-Time-Settings.aspx http://www.example.com/blog/2010/05/check-windows-time-settings/
有了那个 .htaccess,当我浏览到http://blogs.example.com//mark/post/Check-Windows-Time-Settings.aspx并在 Firebug 中查看响应,我看到 302 重定向将http://blogs.example.com/blog/2010/05/check-windows-time-settings/。但是它不存在,所以我收到 404 Not Found。当我告诉它访问 www 时,为什么它却访问 blogs.?
我想知道 OpenShift 别名是否以某种方式覆盖了重定向,但根据重定向文档:
重定向指令优先于 Alias 和 ScriptAlias 指令,无论它们在配置文件中的顺序如何。
我还尝试添加一个明确的陷阱并重写以 blogs.example.com/blog/ 开头的路径(这显然是重定向返回的):
RewriteCond %{HTTP_HOST} ^blogs\.example\.com/blog/ [NC]
RewriteRule ^(.*)$ http://www.example.com/blog/$1 [L,R=302]
我仍然会得到 404 Not Found。事实上,即使是最基本的 URL,http://blogs.example.com/blog/,返回 404。
在这种情况下,我该如何使重定向发挥作用?
2015 年 5 月 27 日更新 #1
尝试在重写块中使用“非”逻辑:
RewriteCond %{HTTP_HOST} !^www\.example\.com/blog/ [NC]
RewriteRule ^(.*)$ http://www.example.com/blog/$1 [L,R=302]
这会导致无限重定向循环,在放弃之前会重定向 20 次。每次重定向仍然以http://blogs.example.com因此仍有某些因素阻止 RewriteRule 在 URL 开头写入“www”。
如果我用以下方式终止 NOT 逻辑,则结果相同$
:
RewriteCond %{HTTP_HOST} !^www\.example\.com/blog/$ [NC]
RewriteRule ^(.*)$ http://www.example.com/blog/$1 [L,R=302]
2015 年 5 月 27 日更新 #2
@Quasidynamic 指出 %(HTTP_HOST) 仅包含主机名,后面没有任何内容。因此,我尝试仅选择以 开头的 URL www.example.com/blog
:
RewriteCond %{HTTP_HOST} ^blogs\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} ^/blog/$ [NC]
RewriteRule ^(.*)$ http://www.example.com/blog/$1 [R=302,L]
没有无限循环,但重定向仍然转到blogs.
,然后重写无法将其发送到www.
。
2015 年 5 月 28 日更新
根据@Quasidynamic 的要求,尝试这个块:
RewriteCond %{HTTP_HOST} ^blogs\.example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/blog/$1 [R=302,L]
正如现在所料,当我浏览时blogs.example.com
,它会被重定向到blogs.example.com/blog/
。由于它仍然符合 RewriteCond,因此它会被重定向到blogs.example.com/blog/blog/
。循环往复。它永远不会转到www.example.com
,这是我从一开始就遇到的根本问题:一旦我将其添加为 OpenShift 子域,无论我尝试什么,blogs.example.com
我都无法再使用 .htaccess 重定向到。www.example.com
答案1
如果您的 [old] 是 blogs.example.com 且 [target] 是 www.example.com/blog:
RewriteCond %{HTTP_HOST} blogs.example.com$ RewriteRule ^(.*)$ http://www.example.com/blog/$1 [R=301,L]
您已经接近了,但是您尝试匹配的/blog 请求并不存在,它只存在于[目标] 网站上,据我了解您的情况。
使用代码 301 - “状态 301 表示资源(页面)已永久移动到新位置。客户端/浏览器不应尝试请求原始位置,而应从现在开始使用新位置。”来自
https://stackoverflow.com/questions/1393280/http-redirect-301-permanent-vs-302-temporary