我有一个“智能错误页面”类,它扩展了ErrorPage和ErrorPage_Controller,基本上是它做了什么a)检测它是否是404,然后b)尝试根据一些自定义搜索逻辑找到潜在的重定向页面。如果在其他位置找到该页面,则会自动将用户重定向到该位置。我知道SilverStripe的基本版本已基于重命名/移动的SiteTree元素,但这更先进。
无论如何,从3.1开始,似乎无法覆盖发送的404标头(虽然这适用于3.0)。
class IntelligentErrorPage_Controller extends ErrorPage_Controller {
public function init() {
parent::init();
$errorcode = $this->failover->ErrorCode ? $this->failover->ErrorCode : 404;
if ($errorcode == 404) {
... some search logic ...
if ($RedirectSiteTreePage)
return $this->redirect($RedirectSiteTreePage->Link());
}
}
}
从3.1开始,上面返回“HTTP / 1.1 404 Not Found”以及“Location:[url]”标题 - 但是似乎无法覆盖404状态。< / p>
知道如何恢复预期的“HTTP / 1.1 302 Found”标题吗?
PS:我已尝试过$ this-&gt; getResponse() - &gt; setStatusCode(302)等,也没有运气。
答案 0 :(得分:4)
由ModelAsController调用init()函数,并且由于此类无法为随机url段找到合适的旧页面,因此在构建自己的响应后重建http响应,因此会覆盖302 404.这发生在ModelAsController的第130行。规避这种方法的一种方法是改变方法并抛出异常,这将阻止对getNestedController的调用。很简单,有一个名为SS_HTTPResponse_Exception的异常。
此代码段适合我(使用302重定向到联系我们页面):
<?php
class IntelligentErrorPage extends ErrorPage {
}
class IntelligentErrorPage_Controller extends ErrorPage_Controller {
public function init() {
parent::init();
$errorcode = $this->failover->ErrorCode ? $this->failover->ErrorCode : 404;
if ($errorcode == 404) {
//... some search logic ...
$response = new SS_HTTPResponse_Exception();
$response->getResponse()->redirect('contact-us');
$this->popCurrent();
throw $response;
}
}
}