匿名ユーザーのキャッシュ制御


7

動的コンテンツをレンダリングするカスタムブロックをいくつか作成しました。残念ながら、キャッシュのデフォルトでは、このブロックの最初のレンダリングがキャッシュされます(匿名ユーザーの場合は更新されません)。キャッシュ制御は、認証されたユーザーに対してのみ機能するようです。私たちは明白なものを見逃していますか?ブロック(またはページ)ベースで匿名キャッシュを制御することは可能ですか?


ブロックはモジュールに実装されていますか?
kiamlaluno

回答:


11

2つの異なるページキャッシュがあります。

内部の動的なページキャッシュは、ブロックおよびノードなどの要素のすべての種類で動作し、これらの要素により提供されるキャッシュタグ、キャッシュコンテキストとキャッシュ最大エージングを使用しています。

内部のページキャッシュは、匿名ユーザーのための完全なページのためであり、唯一のキャッシュ・タグを使用しています。

匿名ユーザーのページキャッシュは、1つのパラメーターで制御できます。

パフォーマンス構成に移動します。

admin/config/development/performance

また、ページキャッシュの最大経過時間を、情報が有効な期間とともに構成します。ページが他の場所にキャッシュされている場合、これはdrupalキャッシュを無効にするのに役立たないため、これはプロキシとブラウザキャッシュにとっても重要です。その後、ページは期限切れになり、再構築する必要があります。ドキュメントによると:

内部ページキャッシュの構成[パフォーマンス]ページでは、ブラウザーとプロキシがページをキャッシュする期間を構成できます。この設定は、内部ページキャッシュモジュールでも尊重されます。他の構成はありません。

しかし、これは真実ではありません。この時間はプロキシとブラウザキャッシュに設定する必要がありますが、内部ページキャッシュはそこに設定した時間を考慮しません。私が見つけた唯一の信頼できる解決策は、モジュールの内部ページキャッシュをアンインストールするか、EventSubscriberに有効期限を設定することです(たとえば、3600秒後)。

/src/EventSubscriber/SetExpiresSubscriber.php

<?php

namespace Drupal\mymodule\EventSubscriber;

use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class SetExpiresSubscriber implements EventSubscriberInterface {

  public function onResponse(FilterResponseEvent $event) {
    $request = $event->getRequest();
    $response = $event->getResponse();
    if ($event->isMasterRequest()) {
      $request_time = $request->server->get('REQUEST_TIME');
      $expires_time = (new \Datetime)->setTimestamp($request_time + 3600);
      $response->setExpires($expires_time);
    }
  }

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

}

mymodule.services.yml

services:
  mymodule.setexpires:
    class: Drupal\mymodule\EventSubscriber\SetExpiresSubscriber
    tags:
      - { name: event_subscriber }

2
\ Drupal :: service( 'page_cache_kill_switch')-> trigger()で内部ページキャッシュを無効にできます。もちろん、ブロックがすべてのページに表示されている場合、それは少し無意味です。
Berdir 2016年

ええ、page_kill_switchは私たちを助けてくれました!ありがとうございました!
gavz 2016年

テストスイッチを使用@gavz curl --headmax-ageで正しいCache-Control:
4k4

また、「RequestPolicyInterface」クラスを使用して、一部のパラメータとリクエストに応じてキャッシュを拒否することもできます。詳細については、api.drupal.org / api / drupal /…を参照してください。
Renrhaf 2017年

パフォーマンス・ページの設定は、内部ページキャッシュの有効期限を制御できるようにするには、サービスのonResponse()この例の方法は、使用するように更新することができ$page_max_age = \Drupal::config('system.performance')->get('cache.page.max_age');、このような3600など将来の秒の固定数に有効期限をハードコーディングするのではなく
デヴィッド・ラニアー


1

内部ページキャッシュを有効にする必要がある場合(つまり、ワニスまたは別のメモリベースのソリューションを使用できない場合)、内部ページキャッシュでに設定された時間を尊重するだけのadmin/config/development/performance場合は、独自のイベントサブスクライバーを追加して、 Drupalが提供するFinishResponseSubscriber。Drupalコンソールを使用してほとんどのイベントサブスクライバーを生成し、FinishResponseSubscriberから他のビットを取得することもできます。結果は次のようになります。

/**
 * Class MyModuleSubscriber.
 *
 * @package Drupal\my_module
 */
class MyModuleSubscriber implements EventSubscriberInterface {

  /**
   * Sets extra headers on successful responses.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   The event to process.
   */
  public function onRespond(FilterResponseEvent $event) {
    if (!$event->isMasterRequest()) {
      return;
    }

    $request = $event->getRequest();
    $response = $event->getResponse();

    $this->setExpiresNoCache($response);

    return;

  }

  /**
   * Disable caching in ancient browsers and for HTTP/1.0 proxies and clients.
   *
   * HTTP/1.0 proxies do not support the Vary header, so prevent any caching by
   * sending an Expires date in the past. HTTP/1.1 clients ignore the Expires
   * header if a Cache-Control: max-age= directive is specified (see RFC 2616,
   * section 14.9.3).
   *
   * @param \Symfony\Component\HttpFoundation\Response $response
   *   A response object.
   */
  protected function setExpiresNoCache(Response $response) {
    $response->setExpires(REQUEST_TIME + 300);
  }

  /**
   * Registers the methods in this class that should be listeners.
   *
   * @return array
   *   An array of event listener definitions.
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = array('onRespond');
    return $events;

  }
}

上記は300秒でキャッシュの有効期間をハードコードしますが、代わりにユーザー設定を簡単に取得できます。


>「Drupal Consoleを使用して、ほとんどのイベントサブスクライバーを生成することもできます」何が必要ですか?モジュール、コントローラー?このコーデックのどこに貼り付けますか?
フランクGiesecke 2017年

こんにちは@ FrankGiesecke、Drupal Consoleを取得する方法はいくつかあります。drupalconsole.comを
markfullmer

こんにちは、コンソールは今実行されます。それでも必要なファイルは?
フランクGiesecke 2017年

0

キャッシュコンテキストを機能させるには、「内部ページキャッシュ」モジュールを無効にする必要があると思います。

「内部ページキャッシュ」を有効にすると、匿名ユーザーのコンテンツはデフォルトでキャッシュされます。

「内部ページキャッシュ」をオフにした場合でも、匿名ユーザーにはキャッシュしないようにDrupalに指示する必要があります

$variables['#cache'] = [
  'contexts' => [
    // The "current user" is used above, which depends on the request,
    // so we tell Drupal to vary by the 'user' cache context.
    'user',
  ],
];

私のためにそれを行います-しかし、おそらく完全には正しくありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.