You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Drupal 9的所有4xx、5xx错误状态自定义错误页面?

在Drupal 9中自定义所有4xx/5xx错误页面的解决方案

一、修复error_page模块的配置问题

如果你已经安装了error_page模块但未生效,按以下步骤排查调整:

  • 确认模块已启用:通过后台“扩展”页面或执行drush en error_page -y确保模块处于启用状态
  • 调整settings.php代码位置:把你添加的代码移到settings.php文件的最末尾,避免被后续配置覆盖
  • 验证模板目录与文件:
    • 确保$settings['error_page']['template_dir']指向的目录真实存在,比如DRUPAL_ROOT . '/../templates/errors'
    • 在该目录下创建对应状态码的Twig模板,命名格式为[status_code].html.twig(如500.html.twig、503.html.twig),模板需包含完整HTML结构(错误页面不会加载主题资源)
  • 检查文件权限:给模板目录和文件设置web服务器用户可读权限(如chmod -R 644 /path/to/templates、chown -R www-data:www-data /path/to/templates)
  • 正确测试错误页面:不要直接访问模板文件,需触发对应错误(比如手动在代码中抛出new \Symfony\Component\HttpKernel\Exception\HttpException(500),或启用维护模式测试503)

二、无需模块的自定义实现方法

如果不想依赖第三方模块,可通过以下两种方式实现:

方法1:自定义事件订阅器(Drupal标准方式,推荐)

创建一个自定义模块(如custom_error_pages),通过事件订阅器拦截错误响应并替换为自定义模板:

  1. 创建模块结构:
custom_error_pages/
├── custom_error_pages.info.yml
├── custom_error_pages.services.yml
└── src/
    └── EventSubscriber/
        └── CustomErrorPageSubscriber.php
└── templates/
    ├── 404.html.twig
    ├── 500.html.twig
    ├── 503.html.twig
    └── error.html.twig # 通用 fallback 模板
  1. 编写模块信息文件(custom_error_pages.info.yml):
name: Custom Error Pages
type: module
description: 'Customizes all 4xx/5xx error pages'
core_version_requirement: ^9 || ^10
package: Custom
  1. 注册事件订阅器(custom_error_pages.services.yml):
services:
  custom_error_pages.subscriber:
    class: Drupal\custom_error_pages\EventSubscriber\CustomErrorPageSubscriber
    arguments: ['@twig']
    tags:
      - { name: event_subscriber }
  1. 编写订阅器代码(CustomErrorPageSubscriber.php):
<?php

namespace Drupal\custom_error_pages\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Response;
use Twig\Environment;

class CustomErrorPageSubscriber implements EventSubscriberInterface {

  protected $twig;

  public function __construct(Environment $twig) {
    $this->twig = $twig;
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::EXCEPTION] = ['onException', 0];
    $events[KernelEvents::RESPONSE] = ['onResponse', 0];
    return $events;
  }

  public function onException(ExceptionEvent $event) {
    $exception = $event->getThrowable();
    $statusCode = method_exists($exception, 'getStatusCode') ? $exception->getStatusCode() : 500;
    if ($statusCode >= 400 && $statusCode < 600) {
      $template = $this->getErrorTemplate($statusCode);
      if ($template) {
        $content = $this->twig->render($template, ['status_code' => $statusCode]);
        $response = new Response($content, $statusCode);
        $event->setResponse($response);
      }
    }
  }

  public function onResponse(ResponseEvent $event) {
    if (!$event->isMainRequest()) {
      return;
    }
    $response = $event->getResponse();
    $statusCode = $response->getStatusCode();
    if ($statusCode >= 400 && $statusCode < 600) {
      $template = $this->getErrorTemplate($statusCode);
      if ($template) {
        $content = $this->twig->render($template, ['status_code' => $statusCode]);
        $response->setContent($content);
      }
    }
  }

  protected function getErrorTemplate($statusCode) {
    $modulePath = drupal_get_path('module', 'custom_error_pages');
    $templateFile = $modulePath . '/templates/' . $statusCode . '.html.twig';
    
    if (file_exists($templateFile)) {
      return '@custom_error_pages/' . $statusCode . '.html.twig';
    }
    
    // 通用 fallback 模板
    $fallbackFile = $modulePath . '/templates/error.html.twig';
    if (file_exists($fallbackFile)) {
      return '@custom_error_pages/error.html.twig';
    }
    
    return NULL;
  }

}
  1. 创建Twig模板:
    比如500.html.twig:
<!DOCTYPE html>
<html>
<head>
  <title>服务器错误</title>
  <style>
    body { text-align: center; padding: 50px; font-family: Arial, sans-serif; }
    h1 { font-size: 50px; }
    p { font-size: 20px; }
  </style>
</head>
<body>
  <h1>500 - 服务器内部错误</h1>
  <p>我们正在处理这个问题,请稍后再试。</p>
</body>
</html>
  1. 启用模块:执行drush en custom_error_pages -y或后台启用模块,测试对应错误即可。

方法2:通过.htaccess配置(仅适用于Apache服务器)

如果你的站点使用Apache,可直接修改webroot下的.htaccess文件,添加ErrorDocument指令:

# 自定义错误页面
ErrorDocument 404 /custom-404.html
ErrorDocument 403 /custom-403.html
ErrorDocument 500 /custom-500.html
ErrorDocument 503 /custom-503.html

注意:将custom-xxx.html替换为你实际创建的静态HTML文件路径,文件需放在webroot目录下。

内容的提问来源于stack exchange,提问作者Sops

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:54:20