【问题标题】:Symfony 5 custom 404 pageSymfony 5 自定义 404 页面
【发布时间】:2020-02-13 21:00:54
【问题描述】:

我正在尝试为 Symfony 5 项目创建一个自定义 404 页面,该页面必须:

  1. 输出一个简单的 JSON 编码字符串,例如“未找到”。
    • 必须从翻译资源中读取所述字符串。
  2. 有一个额外的Content-Type: application/json 标头。

Symfony 文档中有一个部分,that attempts to explain how this can be achieved,但信息似乎不完整/不正确,显然是为 4.X 版本编写的,甚至指向 GitHub 上不存在的源文件。

我已经设法创建了一个错误控制器,但它吞下了所有错误:

# config/packages/framework.yaml
framework:
    error_controller: App\Controller\ErrorController::errorHandler
// src/Controller/ErrorController.php
class ErrorController extends AbstractController
{
    public function errorHandler(TranslatorInterface $translator) : JsonResponse
    {
        return new JsonResponse($translator->trans('not_found'));
    }
}

问题是这会导致返回 404 页面的任何错误(包括内部错误)。

我怎样才能让这个控制器/方法只处理 404 错误,而让框架本身像以前一样处理其他所有问题?

【问题讨论】:

  • 你说得对,文档已经过时了,afaict。 然而是你唯一尝试过的吗?它的字面意思是:“要覆盖非 HTML 错误输出,需要安装 Serializer 组件。” (你做过吗?)。如果您的页面已经使用默认的 _format json(意思是,一切都是 json api)可能已经完成了您的大部分工作。因此,请阅读覆盖非 html 格式的错误输出部分:symfony.com/doc/current/controller/… 如果问题仍然存在,请返回....
  • 也作为一种可行的替代方案,您还可以实现一个监听 kernel.exception 事件的 EventListener,具体到 notfound 异常(不知道确切名称,我相信它是 @987654327 @) 并生成 Response 并将其设置在事件上,这应该立即停止该事件的传播并返回您拥有的任何响应。 EventListeners 也可以通过 TranslatorInterface 注入,所以它对你的控制器几乎没有区别,但更具体到 404

标签: symfony http-status-code-404 symfony5


【解决方案1】:

对于正在为 Symfony 应用程序寻找 JSON 404 页面解决方案的任何其他人:

我一直在寻找一种使用控制器来处理特定错误情况的方法,因为这似乎是表面上最简单的选择,但这似乎是不可能的,或者至少我还没有弄清楚如何。

最后,我找到了使用events and event listeners的解决方案:

配置:

# config/services.yaml

services:

    ...

    # This listener handles only 404 errors in PROD mode
    App\EventListener\ExceptionListener:
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

事件监听器:

// src/EventListener/ExceptionListener.php
class ExceptionListener {
    public function onKernelException(ExceptionEvent $event) : void
    {
        if (
            $_ENV['APP_ENV'] != 'prod'
            || !$event->isMasterRequest()
            || !$event->getThrowable() instanceof NotFoundHttpException
        ) {
            return;
        }

        // Send a not found in JSON format
        $event->setResponse(new JsonResponse($this->translator->trans('not_found')));
    }
}

【讨论】:

  • 欢迎您发布更好的解决方案,而不是仅仅投反对票。
猜你喜欢
  • 2018-11-16
  • 1970-01-01
  • 2010-11-04
  • 2012-10-26
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多