2

我有一个扩展 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 状态。

知道如何恢复预期的“HTTP/1.1 302 Found”标头吗?

PS:我试过 $this->getResponse()->setStatusCode(302) 等也没有运气。

4

1 回答 1

4

init() 函数由 ModelAsController 调用,并且由于此类无法为随机 url 段找到合适的旧页面,它会在您构建自己的响应后重建 http 响应,因此用 404 覆盖 302。这发生在 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;
    }
  }
}
于 2013-10-10T09:34:12.813 回答