我正在关闭一个网站,并在网站的根级别用一个“无人主页”页面替换旧网站。现在我需要设置一些重定向,以便任何对网站任何部分的请求,无论多么复杂,最终都会到达根页面。
我已经尝试过(我认为)应该可行的方法:创建一个.htaccess
包含以下内容的文件:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://www.example.com/ [L,R=301,NE]
但它大多会失败:请求http://www.example.com
仍然可以通过,但https://www.example.com/doesnotexist.html
会抛出 404。(如果没有进行重定向,那么这将是正确的,因为该页面在网站上不存在,但这就是重定向的目的:我希望将此请求发送到https://www.example.com
。)
啊。除了我之外,这个问题的答案可能对每个人来说都是显而易见的;有人可以帮忙吗?
PS:我处于共享托管的情况,因此我必须使用文件来执行此操作,.htaccess
而不是破解完整的 Apache 配置文件。
答案1
如果您要“关闭网站”,那么您可能不应该将旧网站页面“重定向”到单个页面。HTTP 重定向会发送 301 响应代码,通知用户和搜索引擎该页面有已移动(尽管大量重定向到单个页面可能会被 Google 视为软 404。)
相反,您应该提供自定义的“410 Gone”响应。410 通知搜索引擎页面已消失,不会再回来。您的“单页”是自定义错误文档。
例如:
ErrorDocument 410 /single-page.html
RewriteEngine On
# Trigger a 410 Gone for all user requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^ - [G]
检查REDIRECT_STATUS
环境变量的附加条件(在初始请求时为空,但在触发RewriteRule
并设置 HTTP 响应状态后设置为“410”)是为了确保两件事:
错误文档本身的内部子请求(即
/single-page.html
在此示例中)不会触发另一个 410(本质上导致无限循环),从而阻止提供自定义错误文档(在这种情况下将发送默认服务器响应)。并启用直接的请求
/single-page.html
本身也会触发 410,而不会创建重写循环。
(在旁边:不幸的是,使用这种方式检测已经触发的“错误状态”的技术REDIRECT_STATUS
似乎在 LiteSpeed 服务器上不起作用,因为环境变量没有更新期间在 4xx 响应的情况下,请求会有所不同。但是,它针对内部重写进行了更新,即 200 OK 响应,因此它仍然是防止一般内部重写循环的好方法。不过,为什么会有这种差异很奇怪。看起来像是一个错误。)
如果您有需要在错误文档中显示的图像(和/或其他外部资源),请参阅我的答案以下相关问题:
答案2
这不应该有效吗?
RewriteEngine On
RewriteRule ^ index.html
答案3
原因http://www.example.com/
是https://www.example.com/doesnotexist.html
如果客户端通过 HTTPS 访问站点,则您的重写条件明确禁用重写(我相信现在几个主流浏览器默认都这样做,但我没有关于此的来源)。
我假设你这样做是为了防止无限循环,否则会无限重写并将每个请求重定向到(我认为是)规范的 url,而客户端永远无法真正查看该页面。
我相信以下配置正是您想要的。请注意,我在本地服务器上测试了此配置,但我运行的是版本 2.4.46。据我所知,我粗略地浏览了一下版本 2.2 mod_rewrite 文档,升级到版本 2.4,至少就mod_rewrite
具体而言。
RewriteEngine On
RewriteCond expr "! %{REQUEST_URI} -strmatch '/'"
RewriteRule (.*) https://www.example.com/ [L,R=301,NE]
显然,此配置会启用重写引擎,之后它会检查请求的 URI。如果不等于“/”,它会将整个内容重写为仅文档根目录,发出重定向(301
就像您在原始文件中所做的那样),并停止处理任何进一步的规则。您可能需要也可能不需要RewriteBase "/"
在 之后立即声明指令RewriteEngine On
。当我测试这个时,这似乎并不重要,因为我能够毫无问题地重写嵌套目录 URI(即/a/b/c
成功重定向到/
),但是文档确实指出了这一点,所以我在这里传达警告。
再次,我确实测试了这一点,但服务器版本不同,所以希望您不会遇到任何问题。请注意,为了使其正常工作(除非存在技术限制或由上述版本差异引起的差异),您的托管服务提供商需要启用该AllowOverride
指令,可能带有All
选项,尽管我无法确切地确定重写指令工作的最低要求是什么。