web-dev-qa-db-ja.com

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

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

7
gavz

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 }
11
4k4

チェックアウト ルートの応答をキャッシュ不可としてマークするために 'no_cache'ルートオプションを追加

Routing.ymlファイルで:

some.route:
   path: '/some/path'
   defaults:
     _controller: '\Drupal\Some\Controller::response()'
   options:
     no_cache: TRUE
3
joe casey

内部ページキャッシュを有効にする必要がある場合(つまり、Varnishまたは別のメモリベースのソリューションを使用できない)、内部ページキャッシュで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秒にハードコーディングしていますが、代わりにユーザー設定を簡単に取得できます。

1
markfullmer

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

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

「内部ページキャッシュ」をオフにした場合でも、匿名ユーザーに対してキャッシュしないように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',
  ],
];

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

0
bailey86