未在缓存的页面上触发KernelEvents :: REQUEST


13

我正在尝试实现KernelEvents :: REQUEST事件订阅者,以在页面加载时执行某些操作。

无论请求的页面是否存在于Drupal缓存中,我都需要触发该事件-当Drupal提供缓存中的某些内容时,似乎KernelEvents :: REQUEST不会触发。

是否可以使用某个事件来实现这一目标,还是必须以某种中间件形式实现我的要求?


1
REQUEST事件必须被触发,否则将没有响应。恕我直言,您的ES权重很差,并且http_middleware.page_cache(或动态页面缓存)服务正在进一步阻止事件的传播,因此不会触发您的ES。

ES权重/优先级设置为20

正如4k4所写,匿名用户的page_cache是​​一种中间件,它发生在REQUEST事件之前很久。您可以编写自己的早期中间件,但您可能需要重新考虑自己的方式。这么早到底需要发生什么?请记住,匿名页面缓存甚至可能会在其他其他外部软件或浏览器本身上进行涂漆。看看核心统计信息模块如何跟踪页面访问:使用JavaScript在用户执行服务器时对服务器执行ping操作。
贝尔迪尔

@Berdir与Shield模块类似,它将为站点提供HTTP身份验证-因此,我认为这确实代表了一个有效的示例,说明需要在请求中尽早进行处理。(我知道有实现为中间件的D8 Shield模块补丁-由于这种限制,我假设是)。

Answers:


14

动态高速缓存预订的优先级为27的事件。如果希望代码在此之前运行,则必须使用> 27的优先级:

  public static function getSubscribedEvents() {
    $events = [];

    // Run after AuthenticationSubscriber (necessary for the 'user' cache
    // context; priority 300) and MaintenanceModeSubscriber (Dynamic Page Cache
    // should not be polluted by maintenance mode-specific behavior; priority
    // 30), but before ContentControllerSubscriber (updates _controller, but
    // that is a no-op when Dynamic Page Cache runs; priority 25).
    $events[KernelEvents::REQUEST][] = ['onRequest', 27];

运行DynamicPageCacheSubscriber :: onRequest ..


优先级设置为20

我认为您遇到的问题与动态缓存中的事件有关,我编辑了答案。
k4

感谢@ 4k4,但是即使将优先级设置为30,它的行为仍然相同(我重新安装了模块并在进行更改后清除了所有缓存)。还有其他想法吗?

有两个缓存。现在,您具有比动态缓存更高的优先级,仍然有页面缓存。页面缓存在主内核之前执行。您可以卸载此模块并测试其性能是否正常。
2016年

我可以确认这对我有用。我有一个重定向,只会发生一次-在缓存页面之前。当我添加一个优先级时,['checkForRediret', 30];它按预期工作。
Cyclonecode

6

Drupal 8有两个级别的缓存,页面缓存和动态页面缓存。

是的,您可以拦截@ 4k4提到的动态页面缓存。您遇到的问题更有可能拦截页面缓存。钥匙在这里

有一些解决方案:

  1. 添加实现“ HttpKernelInterface”的新类,并以高于200的优先级注册“ http_middleware”(将执行280个操作)。有关参考,请参见“ PageCache”类和实现。

  2. 通过从“ ServiceProviderBase”扩展来创建新类以更改现有的“ PageCache”。在此处查看此参考。然后,创建新类以扩展'PageCache'。

这里是代码参考:

这是StaticCacheServiceProvider.php:

/**
 * Modifies the language manager service.
 */
class StaticCacheServiceProvider extends ServiceProviderBase
{
  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container)
  {
    // Overrides language_manager class to test domain language negotiation.
    $definition = $container->getDefinition('http_middleware.page_cache');
    $definition->setClass('Drupal\your_module\StackMiddleware\StaticCache');
  }
}

这是StaticCache.php:

/**
 * Executes the page caching before the main kernel takes over the request.
 */
class StaticCache extends PageCache
{
  /**
   * {@inheritdoc}
   */
  public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
  {
    // do special logic here.

    $response = parent::handle($request, $type, $catch);

    return $response;
  }
}

希望会有所帮助。


这是非常有益的三江源,我通过实施解决方案1.解决了这个问题
REMCO Hoeneveld
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.