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

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

7
nl ru de
ブロックはモジュールに実装されていますか?
追加された 著者 Brendan,

4 答え

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

内部動的ページキャッシュは、ブロックやノードなどのあらゆる種類の要素で機能し、これらの要素によって提供されるキャッシュタグ、キャッシュコンテキスト、およびキャッシュ最大期間を使用します。

内部ページキャッシュは匿名ユーザー用の完全なページ用で、キャッシュタグのみを使用します。

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

パフォーマンス設定に行きます:

admin/config/development/performance

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

内部ページキャッシュの設定[パフォーマンス]ページでは、次の操作を実行できます。   ブラウザとプロキシがページをキャッシュできる時間を設定します。その設定   内部ページキャッシュモジュールによっても尊重されます。他にはありません   設定。

しかし、これは真実ではありません。この時間はプロキシとブラウザキャッシュに設定する必要がありますが、内部ページキャッシュはそこに設定した時間を考慮しません。私が見つけた唯一の信頼できる解決策は、モジュール Internal Page Cache をアンインストールするか、または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 }
10
追加された
パフォーマンスページ設定で内部ページキャッシュの有効期限を制御できるようにするには、この例のサービスの onResponse()メソッドを $ page_max_age = \ Drupal :: config( 'system.performance)を使用するように更新します。 ') - > get(' cache.page.max_a&zwnj; ge '); では、有効期限を3600などの将来の固定の秒数にハードコーディングするのではなく、
追加された 著者 Vagmi Mudumbai,
内部ページキャッシュを無効にするには\ Drupal :: service( 'page_cache_kill_switch') - > trigger()を使います。もちろん、あなたのブロックがすべてのページに表示されているなら、それはちょっと無意味です。
追加された 著者 KeithB,
@gavzスイッチを使用するときは、 curl --head でテストし、 Cache-Controlで max-age が正しいことを確認します。
追加された 著者 TimoSolo,
また、 "RequestPolicyInterface"クラスを使用して、いくつかのパラメータと要求に従ってキャッシュを拒否することもできます。 api.drupal.org/api/drupal/… 詳細については。
追加された 著者 Saad,
ええ、page_kill_switchが助けてくれました!ありがとうございました!
追加された 著者 Beeelze,

Check out Added 'no_cache' route option to mark a route's responses as uncacheable

routing.ymlファイルの中で:

some.route:
   path: '/some/path'
   defaults:
     _controller: '\Drupal\Some\Controller::response()'
   options:
     no_cache: TRUE
3
追加された

内部ページキャッシュを有効にする必要がある場合(つまり、Varnishや他のメモリベースのソリューションを使用することはできません)、内部ページキャッシュに admin/config/development/performance <�で設定された時間を尊重したいだけです。 Drupalが提供するFinishResponseSubscriberを変更する独自のEvent Subscriberを追加することができます。 Drupalコンソールを使ってほとんどのEvent Subscriberを生成し、それから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秒でキャッシュの有効期間をハードコードしていますが、代わりにユーザー設定を簡単に取得することができます。

2
追加された
こんにちは@FrankGiesecke、Drupalコンソールを取得する方法はいくつかあります。 drupalconsole.com をご覧ください。
追加された 著者 Syed Rashid Mehmood,
>「Drupalコンソールを使ってほとんどのEvent Subscriberを生成することもできます」モジュール、コントローラ?このコーデックをどこへペーストするか
追加された 著者 Asad Saeeduddin,
こんにちは、コンソールが起動しました。どのファイルがまだ必要ですか?
追加された 著者 Asad Saeeduddin,

キャッシュコンテキストを機能させるには、 'Internal Page Cache'モジュールを無効にする必要があると思います。

'Internal Page Cache'を有効にすると、匿名ユーザー用のコンテンツはデフォルトでキャッシュされます。

'Internal Page Cache'をオフにした場合でも、匿名ユーザー用にキャッシュしないように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
追加された