caching-http.md 7.24 KB
Newer Older
Antonio Ramirez committed
1 2 3 4
Caché HTTP
==========

Además del almacenamiento de caché en el servidor que hemos descrito en secciones anteriores, las aplicaciones Web
5
pueden hacer uso de la caché en el lado del cliente para así ahorrar tiempo y recursos para generar y transmitir el
Antonio Ramirez committed
6 7 8
mismo contenido una y otra vez.

Para usar la caché del lado del cliente, puedes configurar [[yii\filters\HttpCache]] como un filtro en el controlador
9
para aquellas acciones cuyo resultado deba estar almacenado en la caché en el lado del cliente. [[yii\filters\HttpCache|HttpCache]]
Antonio Ramirez committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
solo funciona en peticiones `GET` y `HEAD`. Puede manejar tres tipos de cabeceras (headers) HTTP relacionadas en este tipo de
consultas:

* [[yii\filters\HttpCache::lastModified|Last-Modified]]
* [[yii\filters\HttpCache::etagSeed|Etag]]
* [[yii\filters\HttpCache::cacheControlHeader|Cache-Control]]


## La Cabecera `Last-Modified` <a name="last-modified"></a>

La cabecera `Last-Modified` usa un sello de tiempo para indicar si la página ha sido modificada desde que el cliente la
almacena en la caché.

Puedes configurar la propiedad [[yii\filters\HttpCache::lastModified]] para activar el envío de la cabecera `Last-Modified`.
La propiedad debe ser una llamada de retorno (callable) PHP que devuelva un timestamp UNIX sobre el tiempo de modificación de
la página. El formato de la función de llamada de retorno debe ser el siguiente,

```php
/**
 * @param Action $action el objeto acción que se está controlando actualmente
 * @param array $params el valor de la propiedad "params"
 * @return integer un sello de tiempo UNIX que representa el tiempo de modificación de la página
 */
function ($action, $params)
```

El siguiente es un ejemplo haciendo uso de la cabecera `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');
            },
        ],
    ];
}
```

El código anterior establece que la memoria caché HTTP debe ser habilitada únicamente por la acción `index`. Se debe
generar una cabecera HTTP `Last-Modified` basado en el último tiempo de actualización de los artículos. Cuando un
navegador visita la página `index` la primera vez, la página será generada en el servidor y enviada al navegador; Si el
navegador visita la misma página de nuevo y no ningún artículo modificado durante el período, el servidor no volverá a
regenerar la página, y el navegador usará la versión caché del lado del cliente. Como resultado, la representación del
lado del servidor y la transmisión del contenido de la página son ambos omitidos.


## La Cabecera `ETag` <a name="etag"></a>

La cabecera "Entity Tag" (o para abreviar `ETag`) usa un hash para representar el contenido de una página. Si la página
65
ha sido cambiada, el hash también cambiará. Al comparar el hash guardado en el lado del cliente con el hash generado en
Antonio Ramirez committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
el servidor, la caché puede determinar si la página ha cambiado y deber ser retransmitida.

Puedes configurar la propiedad [[yii\filters\HttpCache::etagSeed]] para activar el envío de la cabecera `ETag`.
La propiedad debe ser una función de retorno (callable) PHP que devuelva una semilla para la generación del hash de `ETag`.
El formato de la función de retorno es el siguiente:

```php
/**
 * @param Action $action el objeto acción que se está controlando actualmente
 * @param array $params el valor de la propiedad "params"
 * @return string una cadena usada como semilla para la generación del hash de ETag
 */
function ($action, $params)
```

El siguiente es un ejemplo de cómo usar la cabecera `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]);
            },
        ],
    ];
}
```

El código anterior establece que la caché HTTP debe ser activada únicamente para la acción `view`. Debería generar una
100
cabecera HTTP `ETag` basándose en el título y contenido del artículo consultado. Cuando un navegador visita la página
Antonio Ramirez committed
101
`view` por primera vez, la página se generará en el servidor y será enviada al navegador; Si el navegador visita la
102
misma página de nuevo y no ha ocurrido un cambio en el título o contenido del artículo, el servidor no volverá a generar
Antonio Ramirez committed
103 104 105 106 107 108 109 110 111 112
la página, y el navegador usará la versión guardada en la caché del lado del cliente. Como resultado, la representación del
lado del servidor y la transmisión del contenido de la página son ambos omitidos.

ETags permiten estrategias de almacenamiento de caché más complejas y/o mucho más precisas que las cabeceras `Last-Modified`.
Por ejemplo, un ETag puede ser invalidado si el sitio Web ha cambiado de tema (theme).

La generación de un ETag que requiera muchos recursos puede echar por tierra el propósito de estar usando `HttpCache` e
introducir una sobrecarga innecesaria, ya que debe ser re-evaluada en cada solicitud (request). Trata de encontrar una
expresión sencilla para invalidar la caché si la página ha sido modificada.

113 114
> Nota: En cumplimiento con [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4),
  `HttpCache` enviará ambas cabeceras `ETag` y `Last-Modified` si ambas están configuradas. Y si el clientes envía tanto la cabecera `If-None-Match` como la cabecera `If-Modified-Since`, solo la primera será respetada.
Antonio Ramirez committed
115 116 117 118 119 120 121 122 123 124 125 126 127

## La Cabecera `Cache-Control` <a name="cache-control"></a>

La cabecera `Cache-Control` especifica la directiva general de la caché para páginas. Puedes enviarla configurando la
propiedad [[yii\filters\HttpCache::cacheControlHeader]] con el valor de la cabecera. Por defecto, la siguiente cabecera
será enviada:

```
Cache-Control: public, max-age=3600
```

## Limitador de la Sesión de Caché <a name="session-cache-limiter"></a>

128
Cuando una página utiliza la sesión, PHP enviará automáticamente cabeceras HTTP relacionadas con la caché tal y como se
Antonio Ramirez committed
129 130
especifican en `session.cache_limiter` de la configuración INI de PHP. Estas cabeceras pueden interferir o deshabilitar
el almacenamiento de caché que desees de `HttpCache`. Para evitar este problema, por defecto `HttpCache` deshabilitará
131
automáticamente el envío de estas cabeceras. Si deseas modificar este comportamiento, tienes que configurar la propiedad
Antonio Ramirez committed
132 133 134 135 136 137 138 139 140 141 142
[[yii\filters\HttpCache::sessionCacheLimiter]]. La propiedad puede tomar un valor de cadena, incluyendo `public`, `private`,
`private_no_expire`, and `nocache`. Por favor, consulta el manual PHP acerca de [session_cache_limiter()](http://www.php.net/manual/es/function.session-cache-limiter.php)
para una mejor explicación sobre esos valores.


## Implicaciones SEO <a name="seo-implications"></a>

Los robots de motores de búsqueda tienden a respetar las cabeceras de caché. Dado que algunos `crawlers` tienen limitado
el número de páginas que pueden rastrear por dominios dentro de un cierto período de tiempo, la introducción de cabeceras
de caché pueden ayudar a la indexación del sitio Web y reducir el número de páginas que deben ser procesadas.