mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-01 03:26:36 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			114 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| HTTP кэширование
 | ||
| ============
 | ||
| 
 | ||
| Кроме серверного кэширования, которое мы описали в предыдущих разделах, веб-приложения также могут использовать кэширование на стороне клиента, чтобы сэкономить время для формирования и передачи одного и того же содержания страницы.
 | ||
| 
 | ||
| Чтобы использовать кэширование на стороне клиента, вы можете настроить [[yii\filters\HttpCache]] в качестве фильтра для действия контроллера, отображающего результат, который может быть закэширован на стороне клиента. [[yii\filters\HttpCache|HttpCache]] работает только для `GET` и `HEAD` запросов. Для этих запросов он может обрабатывать три вида HTTP заголовков, относящихся к кэшированию:
 | ||
| 
 | ||
| * [[yii\filters\HttpCache::lastModified|Last-Modified]]
 | ||
| * [[yii\filters\HttpCache::etagSeed|Etag]]
 | ||
| * [[yii\filters\HttpCache::cacheControlHeader|Cache-Control]]
 | ||
| 
 | ||
| 
 | ||
| ## Заголовок `Last-Modified` <span id="last-modified"></span>
 | ||
| 
 | ||
| Заголовок `Last-Modified` использует временную метку timestamp, чтобы показать, была ли страница изменена после того, как клиент закэшировал её.
 | ||
| 
 | ||
| Вы можете настроить свойство [[yii\filters\HttpCache::lastModified]], чтобы включить отправку заголовка `Last-Modified`. Свойство должно содержать PHP-функцию, возвращающую временную метку UNIX timestamp времени последнего изменения страницы. Сигнатура PHP-функции должна совпадать со следующей:
 | ||
| 
 | ||
| ```php
 | ||
| /**
 | ||
|  * @param Action $action объект действия, которое в настоящее время обрабатывается
 | ||
|  * @param array $params значение свойства "params"
 | ||
|  * @return int временная метка UNIX timestamp, возвращающая время последнего изменения страницы
 | ||
|  */
 | ||
| function ($action, $params)
 | ||
| ```
 | ||
| 
 | ||
| Ниже приведён пример использования заголовка `Last-Modified`:
 | ||
| 
 | ||
| ```php
 | ||
| public function behaviors()
 | ||
| {
 | ||
|     return [
 | ||
|         [
 | ||
|             'class' => 'yii\filters\HttpCache',
 | ||
|             'only' => ['index'],
 | ||
|             'lastModified' => function ($action, $params) {
 | ||
|                 $q = new \yii\db\Query();
 | ||
|                 return $q->from('post')->max('updated_at');
 | ||
|             },
 | ||
|         ],
 | ||
|     ];
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Приведенный выше код устанавливает, что HTTP кэширование должно быть включено только для действия `index`. Он
 | ||
| генерирует `Last-Modified` HTTP заголовок на основе времени последнего сообщения. Когда браузер в первый раз посещает страницу `index`, то страница будет сгенерирована на сервере и отправлена в браузер; если браузер снова зайдёт на эту страницу и с тех пор ни один пост не обновится, то сервер не будет пересоздавать страницу и браузер будет использовать закэшированную на стороне клиента версию. В результате будет пропущено как создание страницы на стороне сервера, так и передача содержания страницы клиенту.
 | ||
| 
 | ||
| 
 | ||
| ## Заголовок `ETag` <span id="etag"></span>
 | ||
| 
 | ||
| Заголовок "Entity Tag" (или коротко `ETag`) используется для передачи хэша содержания страницы. Если страница была изменена, то хэш страницы тоже изменится. Сравнивая хэш на стороне клиента с хэшем, генерируемым на стороне сервера, кэш может определить, была ли станица изменена и требуется ли её передавать заново.
 | ||
| 
 | ||
| Вы можете настроить свойство [[yii\filters\HttpCache::etagSeed]], чтобы включить передачу заголовка `ETag`. Свойство должно содержать PHP-функцию, возвращающий seed для генерации ETag хэша. Сигнатура PHP-функции должна совпадать со следующей:
 | ||
| 
 | ||
| ```php
 | ||
| /**
 | ||
|  * @param Action $action объект действия, которое в настоящее время обрабатывается
 | ||
|  * @param array $params значение свойства "params"
 | ||
|  * @return string строка, используемая как seed для генерации ETag хэша
 | ||
|  */
 | ||
| function ($action, $params)
 | ||
| ```
 | ||
| 
 | ||
| Ниже приведён пример использования заголовка `ETag`:
 | ||
| 
 | ||
| ```php
 | ||
| public function behaviors()
 | ||
| {
 | ||
|     return [
 | ||
|         [
 | ||
|             'class' => 'yii\filters\HttpCache',
 | ||
|             'only' => ['view'],
 | ||
|             'etagSeed' => function ($action, $params) {
 | ||
|                 $post = $this->findModel(\Yii::$app->request->get('id'));
 | ||
|                 return serialize([$post->title, $post->content]);
 | ||
|             },
 | ||
|         ],
 | ||
|     ];
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Приведенный выше код устанавливает, что HTTP кэширование должно быть включено только для действия `view`. Он
 | ||
| генерирует `ETag` HTTP заголовок на основе заголовка и содержания последнего сообщения. Когда браузер в первый раз посещает страницу `view`, то страница будет сгенерирована на сервере и отправлена в браузер; если браузер снова зайдёт на эту страницу и с тех пор ни один пост не обновится, то сервер не будет пересоздавать страницу и браузер будет использовать закэшированную на стороне клиента версию. В результате будет пропущено как создание страницы на стороне сервера, так и передача содержание страницы клиенту.
 | ||
| 
 | ||
| ETags позволяет применять более сложные и/или более точные стратегии кэширования, чем заголовок `Last-Modified`.
 | ||
| Например, ETag станет невалидным (некорректным), если на сайте была включена другая тема
 | ||
| 
 | ||
| Ресурсоёмкая генерация ETag может противоречить цели использования `HttpCache` и внести излишнюю нагрузку,
 | ||
| т.к. он должен пересоздаваться при каждом запросе. Попробуйте найти простое выражение, которое инвалидирует кэш, если содержание страницы было изменено.
 | ||
| 
 | ||
| > Note: В соответствии с [RFC 7232](https://datatracker.ietf.org/doc/html/rfc7232#section-2.4),
 | ||
|   `HttpCache` будет отправлять как `ETag` заголовок, так и `Last-Modified` заголовок, если они оба были настроены.
 | ||
|   И если клиент отправляет как `If-None-Match` заголовок, так и `If-Modified-Since` заголовок, то только первый из них будет принят.
 | ||
| 
 | ||
| 
 | ||
| ## Заголовок `Cache-Control` <span id="cache-control"></span>
 | ||
| 
 | ||
| Заголовок `Cache-Control` определяет общую политику кэширования страниц. Вы можете включить его отправку, настроив свойство [[yii\filters\HttpCache::cacheControlHeader]]. По-умолчанию будет отправлен следующий заголовок:
 | ||
| 
 | ||
| ```
 | ||
| Cache-Control: public, max-age=3600
 | ||
| ```
 | ||
| 
 | ||
| ## Ограничитель кэша сессий <span id="session-cache-limiter"></span>
 | ||
| 
 | ||
| Когда на странице используются сессии, PHP автоматически отправляет некоторые связанные с кэшем HTTP заголовки, определённые в настройке `session.cache_limiter` в `php.ini`. Эти заголовки могут вмешиваться или отключать кэширование, которое вы ожидаете от `HttpCache`. Чтобы предотвратить эту проблему, по умолчанию `HttpCache` будет автоматически отключать отправку этих заголовков. Если вы хотите изменить это поведение, вы должны настроить свойство [[yii\filters\HttpCache::sessionCacheLimiter]]. Это свойство может принимать строковое значение, включая `public`, `private`, `private_no_expire` и `nocache`. Пожалуйста, обратитесь к руководству PHP о [session_cache_limiter()](https://www.php.net/manual/ru/function.session-cache-limiter.php)
 | ||
| для объяснения этих значений.
 | ||
| 
 | ||
| 
 | ||
| ## SEO подтекст <span id="seo-implications"></span>
 | ||
| 
 | ||
| Поисковые боты, как правило, с уважением относятся к заголовкам кэширования. Поскольку некоторые из поисковых систем имеют ограничение на количество страниц для одного домена, которые они обрабатывают в течение определенного промежутка времени, то предоставление заголовков кэширования может помочь индексации, поскольку будет уменьшено число обрабатываемых страниц.
 | 
